So, I am building a tablet app with the compatibility library and have run into an oddity I can't seem to figure out. All in one activity, I have 2 tabs (Tab A and Tab B), and 3 Fragments (Fragments A1, A2, and B). The ActionBar.TabListener associated with Tab A handles the adding and removing of Fragments A1 and A2, and the ActionBar.TabListener associated with Tab B handles the adding and removing of Tab B. So far so good.
The strange behavior is exhibited when I launch the activity (so Tab A is selected and Fragments A1 and A2 are displayed from left to right, correctly) click on Tab B (so Fragments A1 and A2 are removed and Fragment B is shown, still correctly) and then click back on Tab A!
Now, Fragments A1 and A2 are showing, but in the reversed order: A2 and then A1!
Has anyone experienced this oddity? If I select Tab B and then Tab A again, they reverse again to be in the correct order, and the cycle continues. According to this article, "If you're adding multiple fragments to the same container, then the order in which you add them determines the order they appear in the view hierarchy", which strangely doesn't seem to be the case now does it.
Any ideas? Thanks in advance!
According to this article, "If you're adding multiple fragments to the same container, then the order in which you add them determines the order they appear in the view hierarchy", which strangely doesn't seem to be the case now does it.
Personally, I wouldn't count on that.
For example, let's assume that you are using a horizontal LinearLayout. Your current code presumably is putting both fragments in the LinearLayout. The way I approach it is to have two FrameLayouts already in the LinearLayout, and to put each fragment in one of the FrameLayouts.
Related
I am making an application that has MainActivity that contains BottomNavigationView and FrameLayout above it. There are 3 Fragments say Fragment A, B, and C.
My doubt is, How do I make switching of Fragments as quick as YouTube Android application? By saying quick, I mean that, when I am on "Home" tab of Youtube application and I switch to the "Trending" tab and again go back to the "Home" tab, it simply loads "Home" tab within fraction of seconds, as if it just hided the inflated page in background and showed up when selected from BottomNavigationView. And also, It inflates the page exactly to the same position where I left.
When I am trying to implement the same in my Application, the RecyclerView in Fragment A re-inflates if I come back from Fragment B.
I am expecting the idea how they do it and in which method they do it (For eg. onStart or onDestroy or onViewCreated)...
If you are using viewpager then Increase the viewpager offset limit
viewpager.OffscreenPageLimit = 2;
Tt's limit is one by default. I hope this may fix your issue.
Thanks
I have a sole activity for a lot of fragments.
In one of the fragments, I must now have a few tabs inside. The ways I can think of doing it is are:
Solution 1 - Creating a new activity just for that, and then implementing ViewPager :
My main concern regarding that solution is this:
So far, on my Activity , I had the following flow :
fragment 1 -> fragment 2 -> fragment -> 3 -> fragment 4 -> and on and on...
Now, suppose I have to implement those Tabs in fragment 3.
from fragment 2, I start a new activity placing a viewpager (with fragment 3 in one of the tabs and other ones in the other tabs). Then I need to be able to show fragment 4 . But since all the fragments in the app are placed on the original activity, it would mix up the flow or even worse. In other words cause either:
It would simply not show fragment 4 and so forth, because the running activity would be the one that is holding the tabs screen, while all the fragments are placed on the original activity, which would in the stack.
Not being able to go back from fragment 4 to the screen with the tabs, and then from 'back' from the tabs screen to fragment 2 , and then 1.
Solution 2 - Activity for result (with view pager):
The activity created for tabs screen could be an activity that results back to the original activity. so the flow would be like this:
fragment 2 -> new activity for result -> send result back to original activity stating that it needs to fire up fragment 4 now -> original activity opens fragment 4.
However, in that case if I go backwards from fragment 4, it would throw me back to fragment 2 instead of that tabs screen(3).
Solution 3 - Tab Layout :
Seems as the best solution.
However, to use that I need getChildFragmentManager() , which requires api 17 and above. My api is 16.
Now, if I use getSupportChildFragmentManager() I would have to use fragment v4. The problem with that is that all my fragments are native, and I can't just change that fragment 3 to be v4, cause then the previous ones and the following ones would have to be v4 as well. Changing all the fragments is not an option since I have about 50 fragments.
Another issue with solution 3
I've encountered , is that it crashes and prints : Error inflating class android.support.design.widget.TabLayout
I tried creating a new folder named values-v21, and created there a styles.xml for the tab layout, but that didn't help for some reason.
I hope I made it clear.
You have another solution derived from solution 3. This is to keep your current navigation(fragment1->fragment2->etc) and build a fragment to hold the ViewPager with simple layouts instead of nested fragments. This way you'll avoid: navigation issues, the problematic nested apis not being present on version 16(which you plan to support) and you'll also avoid a refactoring to use the support fragment api.
And if at a later time you drop support for version 16 you could refactor each of those simple layouts in a nested fragment and use the native getChildFragmentmanager().
I'm currently designing an android app and tried several kinds of general setups, each seeming to have it's downsides.
The app generally consists of three screens (A, B, C), each of those has a list. On list selection it should change to a detail view (A1, A2, A3).
I want each detail view to be swipeable back to it's list.
All I'm sure about is that I have three buttons in the action bar which let the user switch between A, B and C.
Beyond that I tried those setups:
The whole layout is one ViewPager with six fragments. Downside: I have to implement the logic "when and where to swiping is allowed" myself - seemed wrong to me
The layout consists of three fragments, each containing a Viewpager with two fragments. The Viewpager-Fragments are replaced on Actionbutton-Clicks
Downside: I have to forward all State changes to the inner fragments
The layout consists of one Viewpager that gets its Adapter replaced whenever an actionButton is clicked and thus always only has two Fragments at a time
Downside: Fragments are often destroyed and recreated
I hope I made my problem clear.
What general design would you recommend?
I would recommend having fragment with viewpager that would show three fragments with lists. Now, on list item select, I would replace this fragment with item details. When user want to swipe back, i would add custom gesture handling that would call onBack. I would argue if such gesture handling is good design but I'm guessing that you simply need to mimic IOS behaviour (which probably most of us have to do too damn often)
I have an activity that has within it one fragment that takes up the whole screen. At some point in the app flow, the user can go to another screen in the same activity that is composed of two seperate fragments. So you can imagine it as:
Fragment A (100% of the screen) -> Fragment B (50%) + Fragment C (50%)
I can think of two ways of doing this and neither one of them is particularly good. The first is to set a layout for the activity that has in it one container that will hold Fragment A, and then have Fragment A open subfragments B and C inside it. I'm trying to avoid using subfragments because it leads to unusual lifecycle bugs and it also isn't supported by all version of the api.
The second way is to have two layouts for the activity - one layout having a single container, and the second one having two containers and then switch between them at the appropriate moment with setcontentview. I have to admit that I'm not too happy about that solution either, since it means the user will see the screen redraw white instead of a nice transition effect.
Does anyone have any suggestions on how to do this most efficiently? Note that I do want everything to remain under one activity - logically it should be this way. There's no logical point in having two seperate activities for this UI movement.
solved by having two containers and setting the top one to wrap_content height, visibility=invisible and not populating it at all. When I need to move to the two pane setup I populate the invisibile container and set it's visibility to visible which causes it to remeasure. When moving back from the two pane to the single pane call remove on the fragment that populates the top pane.
im going to write a little android app. Nothing complicated, with 6 "screens". 4 of them are on the same view navigation hierarchy level. 2 are subscreens of one of those 4.
For example screen A displays a list with information. By clicking on a list item the app will show screen A1. Screen A1 displays details about the previously selected list item. So Screen A1 is a subscreen of screen A. By clicking on the back button the app shows screen A.
Screen B has also a subscreen, called B1. The other screens are C and D which are on the same view navigation hierarchy as A and B (but not A1 and B1). So A, B, C, and D are on the top of the view navigation hierarchy. The App will start with displaying screen A. In the action bar (or in a sliding menu) you will find buttons to jump to screen B, C and D.
I hope you got an idea of what im trying to do. So normally I would say, every screen is a own activity. Im a big fan of fragments and i normally use them everywhere. In fact I caught myself implementing activities that contains only one fragment, that contains the main view layout. And I can say there is absolutely nothing wrong to do so (Fragments bring big advantages ... )
But now I wonder if it would be a good idea to use a single main activity and change only the fragments in this activity. So screen A, B, C, D, A1, B1 are Fragments instead of activities. So by navigating from Screen A to C I would simply replace fragment A with fragment C in the main activity (instead of starting a new Activity that contains the fragment C). The same way I would implement a navigation from screen A to subscreen A1.
So far I can't see nothing wrong with this approach. In my opinion it would be something like a ViewPager, just without swipe gestures to navigate between screens.
The only thing Im not sure about it (and thats my question) is the memory management. Whenever I do a replace fragment transaction (fragment manager) to navigate from screen A to B the fragment A should be destroyed and the memory should be garbage collected (somewhere in the future), right? When do I instantiate Fragment B? When the user clicks on the button to navigate to B (and repalce A)? Could this bring performance issues (time to instantiate the fragment)?
What if I set all fragments A, B, C, D, A1 and B1 to setRetainInstanceState(true)? Than the class member fields of each screen will be hold in the memory until the MainActivity is finished right?
Does anyone of you have experience with that?
A ViewPage uses some kind of "preloading" fragments and loads only the view layout of the next and previous fragment (setOffscreenPageLimit() )
Do you guys think I have to do something similar to avoid memory and performace issues?