In my app I have the dropdown enabled in the ActionBar. The user has two elements to choose from. Depending on the choice I want a ViewPager to show different contents from different FragmentPagerAdapters. The user has to have the ability to switch all the time.
I've tried to set two different PagerAdapters in the listener with no luck. The Pager would just reload the previous fragments every time. Similar problems are described here and here. However in my approach I don't want to change the content of one adapter. I really just want to switch between two separate adapters.
This whole thing seems really confusing to me. Are there any known workaround for this or is there an alternative solution to my problem?
If it is possible for your application, I would suggest using FragmentStatePagerAdapter instead of FragmentPagerAdapter. Each adapter should be able to store a separate list of fragments, and should keep the saved state of your fragments when you switch to the other adapter.
I've tried to set two different PagerAdapters in the listener with no luck. The Pager would just reload the previous fragments every time.
I am assuming that you are using FragmentPagerAdapter or FragmentStatePagerAdapter. Both of those store their fragments by tag name in the FragmentManager, and therefore this switching approach will not work.
Are there any known workaround for this or is there an alternative solution to my problem?
One approach would be to fork FragmentPagerAdapter or FragmentStatePagerAdapter, replacing the makeFragmentName() method to use an alternative tag syntax, and use the revised adapter class for one of your two.
Related
I am facing a situation as of few days now. I intend to create an activity where there is a TabLayout and a ViewPager.
The tabs in TabLayout corresponds with the fragments/slides in the ViewPager.
Now as of now, each fragment contains the same format,i.e., two TextViews, one under the other, populated with the strings softcoded in string.xml
But this resulted in the creation of too much xml files for the fragments used inside ViewPager.
So I was thinking if it's possible to use only one fragment inside the ViewPager and then programmatically set the strings for those two TextViews in the fragment, that changes each time w.r.t. click on another tab or sliding on the ViewPager area.
This will lessen the no. of fragments to only one, in turn cutting the time to create it and increase the overall performance of the app in which it will be present.
So any insightful help, suggestion, or walkthrough on how to implement this concept - any help on how to do this will be highly appreciated.
You can certainly do that. If you're using FragmentStatePagerAdapter, just initiate the same fragment with different arguments supplied according to it's position and then in fragment check for those arguments and make changes accordingly.
I have an activity with a ViewPager with a variable number of fragments (tabs).
Upon start the activity checks if the associated (complex) data has been loaded. If it hasn't it shows a progress bar view and starts an AsyncTask which fetches the data. Depending on the data the activity creates a number of fragments (tabs) and gives each fragment a sub set of the data.
I currently hold references to the fragments (I know that it is discouraged) and I run into all sorts of problems when the fragments gets reused - I'm giving the data to the wrong instance of the fragment.
So, is there an "android way" of solving this problem?
I run into all sorts of problems when the fragments gets reused
Fragments usually don't get reused in a ViewPager. This is not like an AdapterView where rows get recycled. Using FragmentPagerAdapter or FragmentStatePagerAdapter, a fragment represents one and only one page.
I re-instantiate the ViewPager each time (but the fragments get reused?)
Ah. That's a slightly different problem.
The stock implementations of FragmentPagerAdapter and FragmentStatePagerAdapter make a couple of assumptions:
They are in complete control over the fragments, particularly in terms of running the transactions to add and remove them from the UI
That those fragments will only ever be used by one "logical" ViewPager (IOW, recreating that ViewPager for a configuration change is fine, but that' pretty much it)
Complicating matters is that these adapters store the fragments under certain tags, and therefore if those fragments still exist in those tags, those existing ones will get used, instead of new ones being created.
So, is there an "android way" of solving this problem?
It's unclear from your question why you even need to "re-instantiate the ViewPager". I'm assuming that this is tied to some sort of refresh operation, or something else that is forcing you to go through the process described in your second paragraph.
You could give my ArrayPagerAdpater a try, as it is friendlier about external agents mucking about with the fragments. Since you control the fragments' tags, you can always be certain that you are working with the right fragment -- rather than caching them yourself, just retrieve the right one and manipulate it.
I have a question about whether to use View or Fragment with ViewPager.
Background:
I have an Activity A that contains a ListView. Each ListView item opens Activity B. Activity B shows different content depending on which ListView item is tapped in Activity A.
Activity B's content is shown inside a ListView.
Question:
Now, instead of going back and forth between Activity A and B to switch contents, I have a requirement to implement horizontal view swiping to switch contents all within Activity B.
One solution I found (tried it and it works) is to create many instances of Activity B's ListView and use it with ViewPager + PagerAdapter.
Another potential solution found on the doc (haven't tried it) is to bring that ListView into a Fragment, create many instances of the fragment and use it with ViewPager + FragmentPagerAdapter or FragmentStatePagerAdapter.
My question is, what's the benefit of using each approach? Should I go through all the trouble of bringing the ListView into Fragment or just simply use ListView with ViewPager?
Thanks
A Fragment is a useful approach, I think, when you want to tie some UI business logic to a particular View (or group of). As you know, that individual Fragment has its own lifecycle callbacks and so forth, just as an Activity would.
Rather than having a single Activity host many ListViews through a single PagerAdapter, it may be cleaner to use the Fragment approach because the Fragment only needs to deal with the logic behind driving a single ListView.
This is a very similar situation to one I've just been facing. I'm showing various vertically scrolling forms (consisting of lots of input fields) within a ViewPager. In my case I have gone for the Fragment approach because in my case, it's possible that the ViewPager will actually need to display a completely different kind of view on certain pages. For example, on the first few pages, user input forms might be displayed. But on the final page, a graph will be displayed. A whole separate set of logic is required to drive that graph. To drive those input forms and one graph from a single Activity would get a bit messy, and I would probably need to contain the business logic in several delegate classes or something. So for me, Fragments were the obvious choice in the end. I have my InputFormFragment and a GraphFragment, and they each contain only the applicable logic for the Views that they supply.
Another thing to consider is that in the near future you too may want to display a different kind of View in your ViewPager. Or, you might want to have another UI layout altogether, perhaps one that doesn't use the ViewPager but displays them all side-to-side (e.g. a layout used on a large tablet in landscape mode). With Fragments, things are just far more modular and you could factor the code to do this quicker. If on the other hand you achieved your objective by using a single Activity that contains a simple PagerAdapter and all the logic for the ListViews within, you might find it takes more work in the future to support new kinds of Views or special tablet layouts.
One thing I will say is having implemented Fragments in a ViewPager myself through FragmentPagerAdapter and FragmentStatePagerAdapter, things can get a bit awkward if you have any special requirements; managing Fragments can be tricky sometimes. For example, for my UI I needed to be able to programmatically add and remove the ViewPager containing the Fragments. I also needed to ensure that the adapter in use didn't destroy Fragments once they had been shown, because I needed to collect data from all Fragments simultaneously at a certain point. Furthermore, I had to extend and modify FragmentPagerAdatper to make sure that the Fragments go through their onDestroy() properly and are removed from the FragmentManager when the ViewPager was removed.
Fragments enable a very modular way of constructing UIs for various screen sizes and orientations, and are excellent in how they allow you to encapsulate business logic and lifecycles for individual UI elements. However if your scenario really is just as simple as several ListViews in a ViewPager and you know that you will never need the modularity, then the overhead of Fragments could be an overkill.
I have fragments in a FragmentActivity, that has an ActionBar and Tab navigation. My problem is that I want to call a method on the Fragment. I cannot use findFragmentBy[Id|Tag], because the fragments are initiated and attached by the adapter, and it assigns a custom tag. I saw several solution based on keeping references to fragments, but I really want to avoid keeping any reference to my fragments, as they are handled by the FragmentPagerAdapter. Now I have everything in my Fragment (which is a workaround in my view), but the question still bothers me.
What is the best way to access a fragment instance from my activity, not added by my to FragmentManager, but the FragmentPagerAdapter?
I solved this problem by writing my own Adapter. Since they are pretty straightforward, they are easy to be implemented.
i have been following this tutorial for the pagerAdapter.
http://mobile.tutsplus.com/tutorials/android/android-user-interface-design-horizontal-view-paging/
My problem is that i dont want only to have a different layout for every page but i would like to create a new activity in order to have some java code connected with every layout.Is it possible?
You can't assign different Activities to the pages of a ViewPager. You can, however, assign different Fragments, which should be enough. Check out the docs about the FragmentPagerAdapter class.