Custom CursorAdapter loads data from db every time fragment switched - android

I have an Activity with ViewPager and three Fragments with-in. One Fragment contains ListView with custom CursorAdapter which loads data from database.
I've noticed that my cursor adapter loads data every time I switch Fragments in ViewPager. I think that it's normal and is due to the fact that every Fragment has its own lifecycle.
Regarding this it will be great pleasure for me if the users of the stackoverflow explain about their experience or best practices at all.
Thanks!

ViewPagers maintain the state of only certain number of fragments, which defaults to 1 for both sides of the current selected fragment. For example, if you have 3 fragments, when the first is selected, only first two fragments will be instantiated and have the listview data loaded. Alternatively, if you have the second fragment selected, the first and the third will be instantiated. If you switch to the third fragment, the second fragment will be retained, but the first one will be lost. However, you can set the number of fragments to be retained with calling setOffscreenPageLimit method on viewPager with any number of fragments to retain you need. Though you should remember, that setting the number too high may cause your app to consume too much memory.
For example, if you want your fragment to not reload listview content from db while switching fragments and you have 3 framents in your viewPager, you may write the following code:
ViewPager mViewPager;
mViewPager.setOffscreenPageLimit(2);

Related

Prevent fragment re-create in viewpager

I want to prevent fragment re-create in viewpager , in default way every time you navigate to a fragment in viewpager , android creates a new instance of that fragment.
setOffscreenPageLimit(x) can fix this problem but i don't want to load more fragments in activity's onCreate. Any idea to solve this problem and maintain fragment instance after select for next time?
There are two most used classes for View Pagers are:
FragmentPagerAdapter
FragmentStatePagerAdapter
and they look alike in many ways but not all.
What you need is FragmentPagerAdapter
This will keep the Fragment as you want and not being recreated each time as the following quote say from the official documentantion:
Implementation of PagerAdapter that represents each page as a Fragment that is persistently kept in the fragment manager as long as the user can return to the page.
And also here in the same documentation:
The fragment of each page the user visits will be kept in memory...
Although remember using this, memory will be your responsibility and you will have to manage memory of your Views check the number of pages you are having first if they are many, its not a nice idea to display 50 pages this way. Only may be less than 10 (Tabs may be its the best choice). You are good. Memory management is the only thing to take NOTE here as the documentation itself say:
This can result in using a significant amount of memory since fragment instances can hold on to an arbitrary amount of state. For larger sets of pages, consider FragmentStatePagerAdapter.
So change your adapter to FragmentPagerAdapter and your fragments will be kept in memory not recreated.
Try setting Fragment.setRetainInstance(true). If you use FragmentPagerAdapter, this will cause an existing fragment to 'live' and not get re-created. It will to get detached and re-attached instead.
Try this, where you set the view pager adapter
viewPager.setOffscreenPageLimit(numberOfFragments)

Android: Viewpager with multiple fragments of the same class with fragment transaction

There are already some open threads about this subject but mine is a little different and I can't seem to find out how to do it. This is my problem:
I'm creating a listview (recyclerview) inside a fragment which I put inside my Viewpager. This listview represent a timeline/agenda of the current day. Whenever the user swipe left or right, the exact same listview fragment needs to pop up with different data (data from the day before or after). Whenever you click on one of the items in the listview, the fragment is replaced by a detailed fragment.
This doesn't sounds so hard but here comes the tricky part:
All the examples I see on the internet show different Fragment classes inside the Viewpager which makes it possible to do a transaction from the listfragment to the detailed fragment, and all the examples that use multiple fragments of the same class don't do a transaction to a detailed fragment.
Whenever I'm trying to do the transaction to the detailed fragment, it looks like it can't find the proper fragment container (since there are 3 of the same now). I'm pretty sure of it since the new fragment does appear but the old fragment stays visibile underneath (when I don't use the viewpager it works fine).
If anyone could provide me with a simple example of a viewpager with multiple fragments of the same class that have a transaction to a detailed fragment you would save my day.
Regards

CursorLoader with Fragment inside Fragment

I'm experiencing a really weird behavior and I suppose I'm missing something.
I have an activity that has a Fragment inside. This Fragment has a ViewPager which obviously hosts other Fragments.
To populate that ViewPager I need info from four tables. Once the first loader finishes loading (let's call it 0), I init the other loaders.
The user swipes through the pages and when he/she reaches the last page, the Fragment that is loaded on that last page inits loader 0 again, which takes a huge amount of time to reach onLoaderFinished. If I load that "last page fragment" without being inside the ViewPager, it loads instantly, as expected.
Is there a way to deal with this situation of a Fragment inside a ViewPager using the same Loader that was used to populate the ViewPager itself?
Thanks in advance.
Try calling setOffscreenPageLimit() in onCreate() (after initializing ViewPager). The OffscreenPageLimit sets the number of pages that should be retained to either side of the current page. With this all of your fragments will instantiate. Though you must not do so if there are large number of pages.
I solved the problem by not calling the Loader inside the Fragment and passing the array of data I wanted from the database in a Bundle as a Serializable.

FragmentStatePagerAdapter performance issue

I have implemented an activity that displays fragments in a viewpager. The activity initially displays 5 fragments of a given type (type A). Each type A fragment contains a list of information. When a button is pressed, the fragments are replaced with another tpye of fragments, type B (i.e., fragments that use a different layout and display different information are loaded).
I have implemented this with a ViewPager and a custom FragmentStatePagerAdapter. The custom FragmentStatePagerAdapter overrides the getCount, instantiateItem, getItem, getItemPosition, etc. functions and all works fine. When I press the button the views switch from fragment type A to fragment type B. In order to do this I am using a replace fragment transaction and I also call notifyDataSetChanged on the adapter. The switch from type A to type B fragments is accomplished by checking which type of fragment I need to create in the adapter's getItem function. The problem is that the switching process (i.e., changing from fragment type A to fragment type B and vice versa) takes some time (around 2 seconds) - this delay is quite noticeable and annoying.
This occurs because the adapter's getItemPosition function returns POSITION_NONE. When POSITION_NONE is returned, the viewPager recreates the fragment. Furthermore, when the replace transaction is executed, all items of the adapter are removed and all new ones are recreated. The same happens when I switch back to fragments type A.
Does anyone know if there is a better or faster way to do this? Using a FragmentPagerAdapter should not be a good solution since the number of fragments in the viewPager could grow.
I have commented out the updating of the fragments and the problem is gone so the problem is the time it takes to update the fragments. Is there a way to update the fragments asynchronously? That should take care of the problem.
The ViewPager instatiates by default a minimun count of Fragments. In general the left and right one of the current Fragment. So you don't need to care about the total number of Fragments.
You can control the total number with the ViewPager.setOffScreenPageLimit() method.
Also a AsyncTask seems to be a good idea to manage the intensiv work of your Fragments.

Recreate Fragment of - View Pager - FragmentPagerAdapter

In my application I am using ViewPager from the support library- v4
In main screen I have viewPager which got max 5 Fragment, all fragment belongs to one class ArticlePager
Now in main screen there are list on categories, now the content of the pager is based on that selection,
The problem I am having is, I have used FragmentPagerAdapterwhich stores the Fragment and if the fragment is already exist, It will return the old Fragment without recreating it. That things runs perfectly, but Problem Occurs # the time of orientation change.
For instance
If there are 5 View normally in every fragment For the given position, but There are also some which contains 2-3 views. Now if I change the orientation on page No. lets say 5 which contains only 3 view inside.
So, by now in every category on Page 5 I'll got the view containing 3 view, which is not something I want.
In my application each category contains the pagination
Is there any way such that i can destroy and recreate the Fragment on click of category? or any other work around
Thank you
OK thanks to open source I find my solution, FragmentPagerAdapter I have override the method instantiateItem and got the solution.
This can be easily achieved by FragmentStatePagerAdapter such that it doesn't store the fragment. It recreate it all the time, but I don't want that in 100's of page because of only few pages.
So if I understand correctly, your problem is that after rotation, the wrong set of fragments are in you ViewPager?
Why don't you check the current selected tab in onResume() or onStart() of your Activity, and create/assign a new PagerAdapter for you ViewPager with the correct fragments?

Categories

Resources