Office Hours — Today, June 5

Tuesday, June 2

Mark M.
has entered the room
Mark M.
turned on guest access
Jun 5
4:20 PM
Igor P.
has entered the room
Mark M.
hello, Igor!
how can I help you today?
Igor P.
Greetings Mark!
I have a couple of questions if you allow
first
4:25 PM
Igor P.
in our app we have a complex structure of activity hosting a fragment hosting a view pager which page hosts a fragment with another view pager which of course hosts fragments
Mark M.
that's... complicated :-)
Igor P.
a little
the upper most pager has turned of swipes
but the question is about fragment managers
from different places in the stack i described above we need to add/replace fragments at different levels
so since i pass child fragment managers to each view pager we have several fragment managers in use
and the question is: which fragment manager should i use to do fragment transactions at different levels of the stack described above?
Mark M.
the one that is managing (directly) the fragments that you wish to add/replace
at least, I presume that's the appropriate answer
I'd be willing to put up with a fair bit of physical torture, just to avoid using nested fragments
Igor P.
hm
4:30 PM
Igor P.
:)
Mark M.
what you don't want to do is attempt to mess with the fragments that are the pages in the pagers
assuming that you are using FragmentPagerAdapter or FragmentStatePagerAdapter
they really don't like it when outsiders mess with their fragments
Igor P.
yes, i know this requires additional effort, i try to avoid that
Mark M.
I had to roll my own PagerAdapter implementation (ArrayPagerAdapter) just to try to handle simple scenarios like adding, moving, and removing pages
from your description, the only fragment I see that is not a page in a pager is the root one
Igor P.
but if i use fragment managers directly managing fragments i may well end up with nesting a fragment within a fragment
yes, the only independent one is the root one
Mark M.
oh, your described structure has to use nested fragments
just don't ask me to write that code, or debug it, or be within 100km of it, etc. :-)
any time you are using getChildFragmentManager(), you are nesting fragments, even if there is a pager "in between" them
Igor P.
at the time being i've tried doing getActivity().getSupportFragmentManager() to get the FM to do transactions. from any place within my structure. and it seems to work well. or does it only seem like that?
4:35 PM
Mark M.
that's not how it's supposed to be done
now, it's conceivable that your code will survive, at least for a while
however, I'll raise my minimum distance to 250km :-)
Igor P.
:)
could you suggest what may go wrong with this approach?
Mark M.
ummm... rupture in the space-time continuum?
more seriously, I am surprised that manipulating the same fragment via different managers even works
Igor P.
sounds bad ))
Mark M.
you said in your original description that you used "child fragment managers", which I assume means getChildFragmentManager()
Igor P.
yes
i pass this to the view pager adapters
Mark M.
if in one spot you, say, add() a fragment using getChildFragmentManager(), and later on you try to remove() that fragment using the activity's top-level FragmentManager... if that works, it's a minor miracle
Igor P.
because until i did this pages would never get onStop() and so on on the fragment hosting the pager being replaced...
Mark M.
yes, well, this is one of the reasons why I avoid nested fragments -- they are full of strange behavior
it's probably one of the reasons they didn't release the capability for a couple of years after originally introducing fragments
4:40 PM
Igor P.
with all these difficulties i lean towards the judgement that a ViewPager was never designed to handle tabs at the root level of an application
but only to swipe between the details fragments at the leaf level
Mark M.
I would more generally phrase it that nested ViewPagers scare me about as much as nested fragments
so, if you want tabs at the top level, versus a nav drawer, that's fine, but then don't try having tabs-within-tabs, or something like that
Igor P.
right
Mark M.
if you have that complicated a navigation structure, probably go with a nav drawer anyway for the top-level navigation
Igor P.
ok, thanks, i'll review the design again and see if i can do anything with it
let's move on
4:45 PM
Igor P.
another one on the topic of passing serializable (parcelable) data to activities/services within the same app
4:45 PM
Igor P.
assuming i have a local (same process) service and i pass something serializable with an intent
Mark M.
pass how?
Igor P.
putExtra(...)
on an Intent
Mark M.
no, I mean, how are you using the Intent?
Igor P.
to start a service for example
Mark M.
OK
Igor P.
or put something serializable in a bundle to pass to a bound service with a message
does the payload really gets serialized in this case?
Mark M.
it should
Igor P.
assuming it is a local service
Mark M.
the only case where an Intent is used pass-by-reference that I know of is LocalBroadcastManager
now, when you say "pass to a bound service with a message", what do you mean?
Igor P.
in our app we have a bound service
with handlers on each side
so we have 2-way communication using messengers
4:50 PM
Igor P.
and we pass serializable objects with the messages
4:50 PM
Mark M.
oh
um, to be honest, I'm not sure if the Intent is pass-by-reference or pass-by-value there
IOW, whether it actually crosses process boundaries
stuff like startActivity() and startService() always cross a process boundary
even if the starter and the start-ee are in the same process
Igor P.
i've noticed that after de-serialization we get a reference to the very same object as before the serialization. so we can change object state from both sides...
Mark M.
if I had to guess, my hope is that Messenger recognizes that it is in the same process and therefore does not have to convert the Intent into a Parcel
then presumably the Intent is pass-by-reference
you get that same sort of problem with LocalBroadcastManager
I haven't used Messenger much, so I don't recall ever looking at its implementation
Igor P.
i think that if it was indeed serialized we would get a copy of the object on the other side...
Mark M.
agreed
Igor P.
ok, then it should be the case, thanks
i reckon the parcelable has the same behaviour, doesn't it
?
Mark M.
it should
Igor P.
i see
and the last one, if we have some time...
Mark M.
we have a few more minutes
Igor P.
is there a good approach to implement custom back key navigation in the app?
4:55 PM
Mark M.
what do you mean?
Igor P.
if we need to override default back key behaviour
Mark M.
override onBackPressed() in the activity
Igor P.
say, navigate to a sibling tab instead of exiting the applicaton
Mark M.
personally, I'm not a fan of BACK meaning movement between tabs
you wouldn't see that in a Web app, for example
that being said, onBackPressed() is the right way to implement it
for example, if you try using SlidingPaneLayout for a master/detail pattern, it doesn't offer automatic BACK button support, so you handle it yourself in onBackPressed()
Igor P.
in the Activity?
Mark M.
yes
I don't recall fragments getting called with onBackPressed()
Igor P.
they don't
and i will need to somehow pass the event through view pagers to fragments...
and nested fragment.. )
this is doable, but is complicated
any other good ideas to capture back keys closer to the top of the stack?
Mark M.
I've avoided messing with the BACK option via anything other than onBackPressed()
5:00 PM
Mark M.
I don't even know if it raises a KeyEvent when BACK is in the navigation bar
Igor P.
can't recall
ok, it's clear
thanks for your help!
Mark M.
you are very welcome
and that's a wrap for the chat
this transcript will be posted to https://commonsware.com/office-hours/ shortly
Igor P.
it is
cheers!
Mark M.
the next chat is Tuesday at 7:30pm US Eastern
have a pleasant day!
Igor P.
same to you!
Igor P.
has left the room
Mark M.
turned off guest access

Tuesday, June 2

 

Office Hours

People in this transcript

  • Igor Polovenko
  • Mark Murphy