Office Hours — Today, April 5

Yesterday, April 4

Apr 5
3:55 PM
Mark M.
has entered the room
Mark M.
turned on guest access
Ed T.
has entered the room
Mark M.
hello, Ed!
how can I help you today?
Ed T.
Hi Mark!
4:00 PM
Ed T.
Struggling with something on ConstraintLayout this week
I've got a bunch of label-data rows
trying to get it to collapse an absorb the space
if I set the row to INVISIBLE or GONE
it doesn't fill the space
Mark M.
what is "the row"? do you mean two widgets that are children of the ConstraintLayout?
Ed T.
yes, I have a bunch of TextView items
and under certain scenarios an option might not be valid
so imagine a 'SWITCH' widget
gonzobrains
has entered the room
Ed T.
if you turn it off fields go away and the view collapses
turn it on and they show up and the layout expands
Mark M.
(BTW, hello gonzobrains -- I will be with you shortly!)
gonzobrains
Hi, everyone.
okay, thanks.
Mark M.
do the things that you expect to fill the space have 0dp for the desired axis?
4:05 PM
Ed T.
looking
Mark M.
basically, you need the things that are to fill the space have flexible sizing
if they have a fixed size (dimension or wrap_content), then it doesn't matter what happens around them
while you're looking, let me take a question from gonzobrains, and I'll be back with you in a bit
gonzobrains: your turn! do you have a question?
gonzobrains
I'm writing it right now.
Ed T.
that should collapse in the white space.... checking what you suggested... thanks
gonzobrains
I have a problem where an AlertDialog remains on the screen after the user resumes an app from device sleep. I have tried to dismiss the dialog in the OnPause() of its containing fragment, however the OnPause() is not getting called. I notice that the fragment's OnPause() doesn't get called if the fragment is is displayed from another fragment, but if I allow the user to view this fragment from an option in the sidebar menu, the OnPause() method gets called.
That's the only difference I can seem to find between fragment's that have OnPause() called and those that do not, ie. where they are called from.
There is only one activity in this application, and the previous developer created a "hamburger menu" for displaying fragments and also allows fragments to display other fragments.
4:10 PM
gonzobrains
they are all full-screen and only one fragment is displayed at any time.
Mark M.
it's possible that you are encountering some issue with nested fragments
gonzobrains
Does nesting have anything to do with the backstack?
Mark M.
um, presumably
gonzobrains
I'm trying to figure out the previous developer's navigation setup. He disabled the back button and forces navigation through the hamburger menu and other fragments.
Mark M.
insofar as if the parent is popped off the back stack, it should pop its children
ick
gonzobrains
I've tried forcing everything on the stack to be popped off when the sole activity's OnPause() is called, but nothing happens.
Mark M.
I'm not sure what to tell you
in the scenario where the child fragment is not getting called with onPause(), is its parent fragment being called with onPause()?
gonzobrains
what is a good resource, besides developer.android.com, I could use to understand more about fragments and navigation?
Mark M.
frankly, after the docs and experimentation, we're down to ouija boards and reading the future in tea leaves
this stuff can get fractally complicated
gonzobrains
hmm, parent fragment. I'll have to look into that because the way I see this should work is only one fragment at any given time associated with the main activity since the back button has been disabled.
4:15 PM
Mark M.
I thought your problem case was where the DialogFragment was shown by another fragment
gonzobrains
the code calls supportfragmentmanager.begintransaction().replace().addtobackstack().Commit() all in one go.
ahh, no I solved that problem after your last office hour.
Mark M.
"I have tried to dismiss the dialog in the OnPause() of its containing fragment, however the OnPause() is not getting called"
that's in today's chat
gonzobrains
this is kind of separate. not to do with DialogFragment. In this situation, a fragment is calling an AlertDialog. It's similar though.
Mark M.
all dialogs should be wrapped in a DialogFragment
gonzobrains
oh, well, I'm not using DialogFragment here. It is an AlertDialog that's not getting dismissed.
Mark M.
otherwise, you're unlikely to get configuration changes correct
so, try wrapping this dialog in a DialogFragment, and see if that helps your case any
gonzobrains
could you elaborate? This codebase seems to make ample use of AlertDialog.
Do I have to replace all of them with DialogFragment?
Mark M.
I wouldn't say "replace" as much as "wrap"
have your DialogFragment override onCreateDialog(), and in there put your AlertDialog code
then, show() the DialogFragment
gonzobrains
I will need to research that.
so any dialogs that are displayed from a fragment should be wrapped in DialogFragment then?
Mark M.
any dialogs *period* should be wrapped in a DialogFragment
(note: a few ancient book examples of mine need updating in this regard)
again: otherwise, you lose the dialog on a configuration change (e.g., screen rotation)
unless this code is using the long-since-deprecated managed dialog stuff
gonzobrains
This AlertDialog class appears to be derived from AppCompatDialog (support v7).
4:20 PM
gonzobrains
Does your busy coder's guide have an example of how to do what you suggest?
Mark M.
I think that only ensures that your Theme.AppCompat-based themes work,
let me switch back to Ed for a bit, and I'll return to you shortly
Ed: back to you!
Ed, if you have follow-up from the earlier stuff, or another question, let me know and I can turn back to you
gonzobrains: back to you in the interim
gonzobrains
ok.
Ed T.
I'm here
4:25 PM
Mark M.
Ed: your turn! do you have any follow-up from the earlier stuff, or another question?
in your screenshot, what is the second heading (the "CREDIT CHECK" one) anchored to for its top edge?
Ed T.
A divider
Mark M.
oh, those horizontal bars are separate widgets
what is the upper divider anchored to for its top edge?
Ed T.
so it will go white when I throw the switch off and on
but I was expecting it to collapse
like it does in the other layouts
a LinearLayout would collapse
this doesn't. :-)
:-(
Mark M.
so, the divider above "NO CREDIT CHECK REQUIRED!" -- what is its top edge connected to, via a constraint?
Ed T.
A Text View
Mark M.
the "Down Payment $" one?
Ed T.
Everything has a vertical constraint flowing from the top... down
4:30 PM
Ed T.
to the item above it
Mark M.
OK, and so you're saying that when you make all the widgets between "Finance this plan at 0% interest" to the divider above "NO CREDIT CHECK REQUIRED!" set to View.GONE, that the layout is not collapsing?
if you set it to View.INVISIBLE, then I would expect the results that you're seeing
in principle, if those constraints are set up as you describe, GONE should work
Ed T.
testing it now
that got it!
woot!
thanks Mark
Mark M.
um, you're welcome!
I guess I misunderstood what you tried before, because I thought you had tried that and it didn't work
but, if you have working code, that's all that matters right now
Ed T.
I did try it earlier and it didn't work
but I'm betting I didn't have 'wrap_contents' the last time I tried it
lot of moving pieces there
Mark M.
OK
anyway, glad it is working!
Ed T.
so easy to move a TextView and it switch to a size on you
4:35 PM
Ed T.
:-(
4:35 PM
Mark M.
ah, OK
yes, the drag-and-drop editing has its issues, even with ConstraintLayout
Ed T.
if you're not careful
I moved them around a lot
Mark M.
let me switch back to gonzobrains, and I'll return to you in a bit
gonzobrains: back to you!
Ed T.
sure thing
gonzobrains
I'm just researching all the options now.
Mark M.
OK
gonzobrains
I'm not completely convinced the navigation is set up right, especially because the back button is programmatically disabled.
Mark M.
I can understand that
I agree that the user should be able to get around without the BACK button, but disabling it seems harsh
gonzobrains
Can you explain the reason for wrapping with DialogFragment?
Mark M.
configuration changes
by default, rotating the screen, etc. destroys and recreates the activity
that wipes out any dialog you were displaying
gonzobrains
configuration as in the user rotating the screen to landscape or something else?
Mark M.
right
or any one of the configuration changes, though that's the most common one for mobile devies
er, devices
gonzobrains
ahh, okay. I need to see if the app even permits that. it is an in-house corporate app for use on a single device, so it may be forcing portrait.
but it's good to know that anyway for future reference.
Mark M.
the recommended approach is to show all dialogs via a DialogFragment
gonzobrains
i will look into that.
Mark M.
then, when the fragment is recreated after the configuration change, it will re-display the dialog
gonzobrains
basically, the app disables the back button to force the user to navigate through the hamburger menu.
I think it was a "cheating" way to avoid more complicated navigation issues.
will this re-create the dialog when the device's screen is turned off?
4:40 PM
Mark M.
if needed, yes, it should
gonzobrains
what's happening is that my yes/no alert dialog still remains even though the underlying fragment that created it went away. when the user taps the "yes" button it crashes.
Mark M.
what does "went away" mean?
gonzobrains
I'm still thinking that I need to find a way for the underlying "parent" fragment to get its OnPause() called so I can call the dialog fragment's Dismiss() method.
something with the navigation just isn't right, as if there are two backstacks being created by virtue of how the fragments are being displayed.
I'm not sure.
Mark M.
ah, OK
what is the expected behavior? is the dialog supposed to be there at that point (and work), or not?
gonzobrains
"went away" = the user presses the power button to make the screen go off.
Mark M.
well, that doesn't directly affect a fragment
any more than it directly affects a TextView
so, a fragment won't "go away" just because the power button is pressed
IIRC, it *should* get paused, as its containing activity is paused
gonzobrains
I see the Main Activity's OnPause() being called, but this particular fragment doesn't get it's OnPause() called if it was displayed by another fragment displaying it. but if I put a menu option for this fragment in the side navbar, it will get its OnPause() called.
The exact same fragment, just shown a different way and its OnPause() works.
Mark M.
OK, let's give some names here
gonzobrains
sure.
4:45 PM
Mark M.
can you give me a name (fake or real) for the fragment that is giving you trouble, and for the fragment that is the "another fragment" in the phrase "if it was displayed by another fragment displaying it"?
gonzobrains
I have one activity named MainActivity. Then there is a list of completed purchase orders in a fragment called PoListFragment.
Mark M.
I mean, we can use A and B for all I care -- I just want us to agree on the names :-)
gonzobrains
If you touch on a PO in the listview within PoListFragment, the PO will open up in PrintPreviewFragment.
I choose the print button in PrintPreviewFragment, and a printing progress dialog comes up. if there is a printing error (no printer connected), another yes/no alert comes up and asks if you want to go to the settings screen.
at that point, if the user turns of the screen and turns the screen back on, the application will resume with the main fragment that starts up every time the app starts, but this yes/no dialog remains on the screen.
Mark M.
OK, stop there for a moment
gonzobrains
ok.
Mark M.
isn't the bug that your PrintPreviewFragment went away?
IOW, shouldn't your app be in the same state after the screen turns back on as it was just before the screen was turned off?
gonzobrains
well, yes and no. I agree with you that the menu should allow the user to resume where they left off, but as the app is currently designed the user is supposed to be forced back to the main screen.
Mark M.
oy
gonzobrains
so for the time being I have to work with that restriction.
sorry, i meant "that the app should"
4:50 PM
Mark M.
OK, so, what exactly is causing PrintPreviewFragment to go away? are you specifically running a FragmentTransaction to detach/hide/replace/whatever it?
or popping the back stack?
gonzobrains
lemme check.
Mark M.
dismissing the dialog should be tied to whatever happened to the fragment
so, if the fragment was detached, you'd dismiss the dialog in onDetach()
gonzobrains
ahh, I see that OnStart() for the activity navigates to the start fragment by popping the back stack (inclusive) and then beginning a new transaction to add the "home" fragment to the backstack.
Mark M.
OK, so, your PrintPreviewFragment should be getting a callback at that point
what callback would depend a bit on the transaction that caused it to be displayed
4:55 PM
Mark M.
worst-case, temporarily override all the "negative" callbacks (onDetach(), onDestroy(), onDestroyView(), onHiddenChanged()), see which are getting invoked, then choose the best candidate in which to dismiss the dialog
gonzobrains
yeah, but that doesn't happen if PrintPreviewFragment is called from PoListFragment. It does if I started it from the side-drawer. I see there are two different methods depending on whether another fragment shows a new fragment of if the side-drawer started it. I will try to compare the two.
okay, lemme soak that in.
Mark M.
when PoListFragment shows PrintPreviewFragment, which FragmentManager is it using? getSupportFragmentManager() or getChildFragmentManager()?
gonzobrains
ahh, I haven't tried all of them. I think I only tried onDetach() and onDestroy(). if OnHiddenChanged() works, then that will fix this dialog problem in the short-term, but I should still see if the code is abusing this navigation/backstack system.
getSupportFragmentManager()
Mark M.
oh, it probably is :-)
hmmm, OK, that's the same as what MainActivity is using, so it's not a nested fragment issue
gonzobrains
you know, I solved my last problem i discussed with you a few days ago by invoking the DialogFragments using getChildFragmentManager() though.
I didn't think I should use child in this case though.
Mark M.
it doesn't feel like it is a child fragment scenario to me either
but, I don't know much about your code base
BTW, Ed: any quick final questions?
Ed T.
it's a simple one if you have time
gonzobrains
I was wondering, since the back button is disabled, if I should just pop whatever is currently on the backstack before navigating to any new fragment.
Ed T.
if not... you can cal lit
'call it'
gonzobrains
go for it, Ed.
Mark M.
Ed: go ahead
5:00 PM
Ed T.
is there an easy way to do a "%S Customers"
where that is a var passed in
to a strings.xml resource
or would you advise against it?
Mark M.
no, that's fine
use a lowercase s
"%s Customers"
Ed T.
will do
thanks!
have a great evening
Mark M.
and there's a variant of getString() that takes a varargs that can be used to fill in the %s, akin to String.format()
Ed T.
ty
Mark M.
you might also look into plural resources, since you wouldn't want "1 Customers"
Ed T.
have a great evening Mark!
cheers
Ed T.
has left the room
Mark M.
OK, that's a wrap for today's chat
gonzobrains
thanks again!
Mark M.
you're welcome!
the transcript will go up on https://commonsware.com/office-hours/ shortly
gonzobrains
ok.
Mark M.
the next chat is Monday at 9am US Eastern
have a pleasant day!
gonzobrains
cool, thanks.
gonzobrains
has left the room
Mark M.
turned off guest access

Yesterday, April 4

 

Office Hours

People in this transcript

  • Ed Tidwell
  • gonzobrains
  • Mark Murphy

Files in this transcript