I'm having a bit of trouble implementing a design based around multiple ViewPagers.
At a high level, I have a FragmentActivity with just a FrameLayout as it's content. I have 3 different Fragments that I want to display. All 3 are full screen and only 1 will be used at a time.
Fragment 1 is a basic fragment with some TextViews and ImageViews.
Fragment 2 has a ViewPager and a FragmentPagerAdapter that feeds it several simple fragments.
Fragment 3 has a ViewPager and a FragmentPagerAdapter that feeds it several simple fragments (that are different from Fragment 2)
In my FragmentActivity onCreate() I get the FragmentManager and begin a transaction to replace whatever is in my FrameLayout with a new instance of Fragment 2.
At this point everything is working as expected. My ViewPager in Fragment 2 works perfectly.
Now I have a menu option that replaces the Fragment 2 in my FrameLayout with a new instance of Fragment 3. This also works fine.
The problem arises when I try to put Fragment 2 back into the FrameLayout with another replace transaction. I see my PagerIndicater at the top, but my pages are blank.
I've tried just creating a new instance of my Fragment 2 and calling a replace transaction. I've also tried setting a tag on my Fragments when I call replace and adding a findFragmentByTag check before my replace instead of creating a new instance. Both gave me the same result of blank pages after my second replace.
For reference
My first design was simply a FragmentActivity with a ViewPager and a ViewIndicater. I only had Fragment 2 and Fragment 3 from my description above and a menu option to switch between them. To switch I had 2 different FragmentPagerAdapters defined and just called ViewPager.setAdapter to set the selected FragmentPagerAdapter. This was working perfectly, but now I need a new top level Fragment that isn't using ViewPager at all. This is why I decided to move my ViewPagers out into their own Fragments. My idea being that I would just swap in my fragments to a FrameLayout.
I don't have my code in front of me right now so I can't post any, but I'll add some code to my question tomorrow to help facilitate answers.
This question is a possible duplicate of Navigating back to FragmentPagerAdapter -> fragments are empty.
If your app can handle it (API 17), use getChildFragmentManager(). This problem seems to occur when using a Fragment to host your ViewPager and using FragmentPagerAdapter. Changing to FragmentStatePagerAdapter seemed to fix the problem as well, but I still think using getChildFragmentManager() is the smartest thing to do.
brockoli you can used not "good way". But for my it's worked.
You can use in view 2 layouts, where you bind fragments. First - for fragment with fragments. Second - for other fragments.
On replace fragment with fragments do not replace, but only change visibility first layout to gone and add new fragment to second layout. On back, remove fragment from second layout and set visibility for first layout to visible.
Related
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 followed the following tutorial to create an app with a material design tabbed interface with the result here.
My question is that in my TAB3 (a fragment) I have a Spinner at the top to change between 2 types of data view, a ListView and a TableView (diary).
I am a complete beginner programmer and I am not sure how to implement this. I have searched and know I cannot create a Fragment within a Fragment. I was thinking of communicating from the TAB3 Fragment to the parent Activity (though I'm not sure if this should be the MainActivity or the ViewPagerAdaptor) via an interface to swap out the TAB3 fragment to another one when selected with FragmentManager. Or is there a way I'm missing to swap out the ListView to a TableLayout on the fly within the Fragment?
I have searched much on this with my limited understanding and most tutorials can explain how to communicate from an activity to a fragment or fragment to fragment, but my situation seems a bit different in that all this exists within the TAB3 fragment and I don't know how to switch out a portion of that fragment.
If I understand you correctly, just make fragment in tab 3 as container and use nested fragments.
I've created an app, that has a main activity with a drawer menu so the user can click on some option and a fragment is open inside the activity.
What I'd like to do is to have several screens in one of the options and to navigate between them by tabs/slide the screen.
I saw an example of doing it inside one activity and with a fragment per 'sub-screen', my question is: how can I do it when I'm already 'inside' a fragment?
Thanks
Fragments can support having other Fragments inside them. The key to making this work is to remember to use getChildFragmentManager() to get the Fragment's FragmentManager instead of getFragmentManager() which gets the Activity's FragmentManager.
If you want to swipe between views, use a ViewPager inside your Fragment UI. The ViewPager will use a FragmentPagerAdapter to handle the Fragments for display.
I am writing an android app that will have a number of different screens that I would like to swipe between, each screen will be a full page except for action bar header. On each screen there is the ability to open up another screen which will also be multiple screens that I would like swipeable. What is the best way to handle this. Do I have one fragment manager that holds all the screens and handle the onPageScrollStateChanged to only allow swipes between the current accessable screens or would I be best off nesting the fragments. I hope the above makes sense.
Thanks in advance
Sounds like you want to use a ViewPager to to swipe between views (Fragment extends View)
You could either:
In a single activity use a FragmentManager that switches between the parent and child Fragments, each with their own ViewPager and nested Fragments
Start a new activity to hold each ViewPager
Both are valid, if the Fragments need to communicate with each other or the Activity option one might suit the project needs better.
For the swiping between views you indeed need a ViewPager
For the nested fragments I would use a wrapper. I struggled a lot with fragments and found that this is the best way. A wrapper is very simple. This is just a fragment that holds other fragments. In the onCreate() of this fragment you get the childFragmentManager and add the fragment you originionally wanted to add. If you want to go to a new fragment you simply get the childFragmentManager again and replace the current item. This way you have nested fragment. You can add this to the backstack in order to get back navigation, but you need to override onBackPressed() inside your activity and call the method popBackStack() from the fragmentManager in order to get the first fragment back.
If you have any questions, comment below.
I have a FragmentStatePagerAdapter which is used as the ViewPagerAdapter for my ActionBar etc. I am trying to change a fragment and add the previous one to the backstack. It appears, however, that this is not possible.
If I look at the Code it seems as though the only way around this is to destroy the old Fragment then add the new one. This is not optimal for what I am trying to do (multipage form). What I really want to do is take the existing fragment and detach it, then add a new fragment and add it to the backstack.
I have tried this without the ViewPager and it works flawlessly. Short of rewriting my own FragmentStatePagerAdapter class that allows me to replace items in the Fragments List is there anything else I can do?