i am new to android. i noticed that on implementing the adapter of the view pager the getItem() will result in returning two adjacent fragments. How can i skip this default loading and load only the fragment in the current page. Please help me.
You should not do that. Please note that when swiping to next page two fragments are visible at the same time so they have both be created.
You can use ViewPager.setOffscreenPageLimit(1) for this. I've used that to keep all my three fragments alive. I Don't know what happens if you set it to 1.
Confusing, this is from the documentation. It says this value defaults to 1 but when I was working on that I got always two fragments like you do:
You should keep this limit low, especially if your pages have complex
layouts. This setting defaults to 1.
Related
I have an scrollable tabs + swipe activity with 3 different fragments on it. It works well but I don't want my fragments to be destroyed when I navigate between them. For example, when I create the activity, it's shown the first fragment but it's created the second one too. When I swipe to the second fragment, the third is created, so I can swipe to the third one and it will be created before I open it. When I return to the second one, my third fragment still stays created but when I return to the first one, the third fragment is deleted.
There would be any way to avoid this? I don't want my fragments to be deleted when I navigate between them.
If you use a ViewPager, it has a method called setOffscreenPageLimit(int limit). Try and see if setting that higher works
This answer should help you figure out what's going on. Pretty much you are most likely using a FragmentStatePagerAdapter, when you should be using a FragmentPagerAdapter. That keeps it from deleting fragments not in view.
If, for performance reasons, you need to have the fragments deleted when they aren't being used, there are other options. Either look at why the performance is that bad when you have only 3 tabs (It shouldn't be unless you are doing something wrong with a listview, or have a map open, etc.) or you can code the fragments to save their state when they are being destroyed (which should be happening anyways with a FragmentStatePagerAdapter).
If that doesn't help, we'll need more info on what you are doing exactly to help.
I have an android application where I followed http://developer.android.com/training/animation/screen-slide.html to setup.
However, I have quite a few fragments in the ViewPager (not at once) and I'd like to destroy them when I'm not on them. To put it into perspective, I have one fragment that gets created every time the ViewPager's getItem(int position) is called - which is around 365 times (one for each day of the year). All was good until I added an ImageView to one of the pages (12 in total at the end of it...) and now I'm running out of memory if I try view 3 of those page fragments.
My question is, how do I remove/destroy the fragment when its not the current page? I tried popping the BackStack of the FragmentManager, but that didn't work (it doesn't seem to have anything in the BackStack, but then again - I could have been calling it in the wrong place which was the getItem() function)
I'd provide code, but its quite a lot to look through for the important parts. It has the exact same structure as the Tutorial in the link above.
Thanks
If you get memory issue after adding imageViews to pager, why not focus on the memory aspects of the bitmap you construct for the imageView just added to your app?
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
Note that pictures from device cameras can be very, very big and can cause memory issues very quickly and , IMO you should focus first on that.
IMO , the standard ViewPager and standard Adapter are OK at managing memory, even if you have lots of Fragments that you cycle through the pager.
And, its a little complex to take on the issue of explicitly destroying pages, reloading fragments in a ViewPager due to the amount of detail in collaboration among the pager and the adapter.
If you want to take on the complexity of the adapter and pager yourself, you will need to get into the source code for the pager and for the adapter you select:
* {#link android.support.v4.app.FragmentStatePagerAdapter},
* {#link android.support.v13.app.FragmentStatePagerAdapter};
As you can see from many posts on the topic of managing fragments in a ViewPager, its not enough to simply call 'destroyItem()' on the adapter or to simply remove a fragment from the ListArray bound to the adapter before calling notifyDataSetChanged() on the adapter. You also must know exactly how the operation of getItemPosition works along with the ViewPager in order to get the result you want.
It will probably take lots of time to work through the ViewPager approach .
Solve it if you can by first focus on the bitmaps.
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.
Offtopic: thank you for your time and sorry for my English.
The problem is the lag when swiping on ViewPager.
The configuration used is a TabHost with Tabs (and dummy content), ViewPager with four fragments and FragmentPagerAdapter to manage it.
All 4 fragments have a list, some with other widgets in the layout. The thing is 2 fragments, or the 2 list in those fragments are quite heavy. The list items are LinearLayout with ~10 weighted items inside binded with a CursorAdapter. I know here resides the big problem, but I have struggled my small head to get an approach to this "percentage width" list item without any luck.
But, after some logs, I have figured out that the 3 managed fragments are "invalidated" during every swipe. I mean "invalidated" because what I see is every list binding items many ( a lot of ) times. And because of the redrawing of the 3 list, including my 2 heavy lists, the lag occurs.
2 things more to point of my code: I'm using cursor loaders, that I'm sure are not the cause of recreation because loader callbacks aren't arise on swipe.
On FragmentPagerAdapter.onPageSelected I'm only updating the current tab.
Setting ViewPager.setOffScreenPageLimit(3) to keep 4 fragments alive do things worse. Even when I swipe from fragment 3 to 4, the list on first fragment is re-rendered, what I really don't want and don't understand.
My workaround is using the onPageSelected to set the visibility of current list view to Visible and the others hidden. With these approach the lag disappears (let's say 95%), but I can see, when I scroll the empty list view before is created.
I would like to ask, if I'm wrong at some point, maybe missing an important idea. If anyone has a possible solution, maybe avoiding those recreations (I don't know how) or, if other people is getting same, and there is nothing to do to solve it.
I will try to take I look to ViewPager source, but I've just opened the file woouu..
I will try to get a test project with this issue.
Thank you very much.
I use ActionBarSherlock compatibility library and experience a strange behavior when paging between tabs of Action Bar. Each tab contains a simple Fragment, nothing special. I observed that fragment's onCreateView method is called too often even though there is no screen orientation change. It looks like some kind of pre-caching. I have three tabs there, when the activity is created, the onCreateView is called only for the first two fragments. The last fragment doesn't create view until I page one step forward. The same behavior occurs when paging from the last tab to the first.
Has anybody any idea why this occurs? I would assume creating all views at once, when the parent activity finishes its creating. I don't want to create views again and again, there are no changes in the fragments, they are static. It has no sense and causes paging to be sluggish a bit...
After a few hours I found what's happening there. ViewPager has a default setting DEFAULT_OFFSCREEN_PAGES which sets the maximum number of views (fragments in my case) to be stored in the view container of ViewPager. It is obviously some kind of resource optimization; invisible views can be thrown away and restored when needed.
There is nothing easier then change this value by setOffscreenPageLimit(int limit) setter which I overlooked.
I think it was done consciously to increase user experience.
The same way ViewPager from compatibility lib is implemented.
Anyway, sources are available.