Office Hours — Today, August 8

Thursday, August 6

Mark M.
has entered the room
Mark M.
turned on guest access
Aug 8
4:05 PM
sudokai
has entered the room
Mark M.
hello, sudokai!
how can I help you today?
sudokai
Hi, good evening
4:10 PM
sudokai
I was wondering, imagine I have a screen A, from which I can go to B, and then to C
How can I open C directly
But then when I press back, go to B
Press back again, go to A
Mark M.
which of these are activities and which of these are fragments?
sudokai
Let's say all of them a fragments of a main activity
Single activity pattern
Similar to the one in your book
Mark M.
the Navigation component has some deep link options that might cover this
sudokai
We don't use Navigation, can you do this manually?
What we currently do is to actually render A, then add B on top of A, then C on top of B
It all happens pretty fast, but we literally have all the layers on top of each other
As we don't replace the fragment
We use "add"
It didn't seem like a best practice to me
4:15 PM
sudokai
But again, I'm kinda newbie myself so I don't know any better
Mark M.
give me a couple of minutes to do some research
sudokai
Sure. I mean, I'm sure other apps don't do this.
Imagine if you're 5 layers deep.
Mark M.
true, but not that many apps are likely needing this capability
I was hoping that TaskStackBuilder had fragment options, but it doesn't
alternatively, have your Activity override onBackPressed() and handle back navigation in a custom fashion
sudokai
Today I learned about TaskStackBuilder
4:20 PM
sudokai
First time I've seen it
Mark M.
if your answer was that A/B/C were activities, that would be your solution
it feels like there should be a better answer for this for fragments than I am seeing
sudokai
So you just add the fragments to the backstack?
Mark M.
that's what the Stack Overflow answer that I linked to did
it's from 2014, which worries me
sudokai
To me, this seems like a common thing you would want to do
Mark M.
I think most apps have simpler nav, where forward and backward are reflections of each other
in your case, it would be A->B->C->B->A, with the latter two being back navigation
deep linking is one scenario where I see a need for what you want, and AFAICT we don't have great fragment support for that, inexplicably
personally, I haven't run into this scenario yet, so I don't have a go-to solution for it
FWIW, based on the search results I'm seeing, it feels like the Navigation component does offer something for this
sudokai
I see the stackoverflow answer uses "replace"
4:25 PM
sudokai
We use "add"
Not sure why we use "add"
Instead of a single layer, we just pile them up
Mark M.
the implication is that you then have all three fragments there at the same time
sudokai
Exactly
Mark M.
right
sudokai
Why would the previous developer do something like this??
Mark M.
¯\_(ツ)_/¯
4:35 PM
sudokai
I think it was done to load the screens fast
When you press back
Because the data fetch would be done
on the first render
But I don't think this is the way to go
4:40 PM
Mark M.
agreed -- a fragment is not really meant to be a data cache
if you are using repositories, you could arrange to have it pre-fetch the data
sudokai
Mmm, how do you do that? I mean when?
Mark M.
have C's viewmodel hint to the repository "hey, warm your cache for this stuff"
sudokai
When you open screen C?
Mark M.
yes
sudokai
Okay, yeah, I mean, it's the only way right, but if the navigation graph changes, then you would need to change this part of the code
Mark M.
sure
sudokai
Whereas using the fragments as natural data caches would require no work on your part
Just bad performance for the user
Haha
4:45 PM
sudokai
Another question: is there any lifecycle method that runs when a fragment becomes visible?
Mark M.
a fragment does not become visible or invisible -- that is a View thing
so, what do you mean by "becomes visible"
?
sudokai
When it's shown on screen
Mark M.
again, that is a View thing
you need to be thinking in terms of the transactions that you are running
so, for example, if you use hide() and show(), then onHiddenChanged() is the callback
sudokai
Yeah, but the transactions are async
themselves
Mark M.
so?
4:50 PM
sudokai
So when I add a new fragment, I don't know when it becomes visible
I call commit
Mark M.
you are calling something before that
sudokai
But the views are not there yet
Mark M.
if you want to be reacting as a fragment, you need to be thinking in terms of the fragment transaction operations that you are performing, *before* the commit() call
so, for example, if you use hide() and show(), then onHiddenChanged() is the callback
if you use attach() and detach(), then onAttach() and onDetach() are the callbacks
and so on
if, instead, you want to be thinking in terms of the views, then you would need to add global layout listeners or something to those views
what is the actual problem you are trying to solve by finding out "when it's shown on screen"?
sudokai
It's a piece of code I'm still looking into
But basically, I have bottom tabs navigation
And each tab has its fragment and subtree
The thing is, when I open the app
The fragments of the tabs that are not selected are already created
Not sure how that's happening
4:55 PM
sudokai
So when I switch click on another tab of the bottom tab navigation
No fragments are created
I just need to find out when they become "visible"
Mark M.
isn't that "when the user clicks the tab"?
sudokai
Yeah, but that's the problem right there
Sorry, the code is very convoluted
I'll need to take another look before I understand it
Mark M.
life is very convoluted :-)
sudokai
I did not write this
Mark M.
basically, somewhere, you have a listener for those tabs, and that listener is doing something to switch tabs (hide() and show()? replace()?)
sudokai
add
I don't know what's doing, but all I'm seeing is "add"
Mark M.
that's really not possible if the tabs already are created
sudokai
I need to look into it more
Mark M.
I mean, if the user presses Tab 1, then Tab 2, then Tab 1, you would crash on the second Tab 1 add() call, as the fragment would already be added
5:00 PM
sudokai
yeah, that makes sense
5:00 PM
Mark M.
for pre-created/pre-added fragments, hide() and show() is one option to basically control which fragment's view hierarchy is rendered
(where hide() and show() are methods on FragmentTransaction)
but, yeah, you'll need to figure out how those tabs work
sudokai
I think I need some time to look into it. I'll probably come back next time.
It's all homegrown
Crazy code
Mark M.
basically, though, you probably want to be doing whatever it is you are trying to do based on the tab being clicked, rather than trying to react to some sort of state change in the fragment
sudokai
We don't use the material component for it
Mark M.
click events are much more straightforward
oh
then, yeah, I can't really comment on what you have :-)
isn't legacy code fun?
sudokai
I'll let you know next time, when I figure it out
But I definitely have an issue with some async calls there
Yeah
Haha
Mark M.
OK, well, that's a wrap for today's chat
next one is Tuesday, 8:30am US Eastern
sudokai
Thanks Mark, as always!
Mark M.
have a pleasant evening!
sudokai
Same
sudokai
has left the room
Mark M.
turned off guest access

Thursday, August 6

 

Office Hours

People in this transcript

  • Mark Murphy
  • sudokai