I'm trying to build an application made of 10 Fragments using ViewPager along with FragmentStatePagerAdapter (and setOffScreenPageLimit(3)). There are 5 Fragment which are going to perform realtime updates modifying TextViews, Graphs and ProgressBars (so they're always performing actions on the MainUi thread). In this scenario, when I slide between Fragments the animation is very laggy (takes 1 to 2 seconds to change fragment when I see them for the first time, then it takes less but there are always lags).
What I'm asking is: how can I improve the smoothness of transactions?
Should I change my way to implement fragments (using FragmentManager instead of ViewPager), slow down the animation or perform some sort of operations before the sliding?
I have not so much experience in Android so any help is appreciated.
Eventually, I've found a solution consisting of the incrementation of setOffScreenPageLimit argument.
Related
I have a fragment that has a viewpager, let's call it fragmentA. I use a FragmentStatePagerAdapter for this. The problem occurs when I am replacing fragmentA with another fragment. For some reason, it causes the app to kind of lag for one or two seconds before actually committing the next fragment. The animations are also not run. I am thinking that Android is destroying the inner fragments before replacing it, and the inner fragments have lists in them which causes the app to lag. Is there a way to work around this?
It all depend on the speed and RAM of the device. The viewpager will have to poulate all its children before displaying on the screen. As a result, lag on some devices
I have a viewpager in my layout , that viewpager holds a set of 10 fragments . Each fragment has a list view , which is asynchronously populated . I m currently using FragmentPagerAdapter as adapter for the viewpager and the API calls to populate the list view is done in onCreateView of each fragment . The swipe is insanely slow and app closes itself because of the memory issues .
How to achieve smooth and responsive (viewpager+listview) like Google Play does ?
Smooth swiping + good cache of list items ?
There are many ways to improve the performance of a ViewPager integrated with a ListView.
First, change the PagerAdapter from FragmentPagerAdapter to FragmentStatePagerAdapter. The difference is that you load 10 pages within the pager. And if you went through all the manager will only put the pages in onStop() therefore it will reserve space. However using FragmentStatePagerAdapter will destroy these pages but will save their instance using the onSaveInstanceState method. So when you get back it won't take much time to load and you will be saving memory.
Usually FragmentPagerAdapter is used with 3 pages or less.
The second way to improve performance (but it drains the battery faster) is adding this line to your AndroidManifest.xml under your application tag:
android:hardwareAccelerated="true"
The third way is detecting the swipe gesture. You can do this by implementing onPageChangeListener then in the implemented method onPageScrollStateChanged you check if the page is Idle then add the ListView. Otherwise, stop the use of ListView and scroll to the next page. Here is a better explanation of this point.
Hope some of these points can help you out to achieve better performance.
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.
Is this possible to preload Fragments for ViewPager so that there's no lag when user swipes to next page? I've been trying two kinds of adapters but there's no use in switching from Fragmentstatepageradapter (I am using fragments to generate N pages) to fragmentpageadapter. I've got a lot of bitmaps to load in my pages. Setting viewpager offscreen pages doesn't help. Is there a way to preload them and inflate in backgdound? I know this is a silly question but I am a bit desperate about performance. Basically in my app when user scrolls to next page there is kind of lag, just between pages, and it's so annoying... Please help or point the right direction. I am targeting Gingerbread so I need to use that what Android Support gives.
Is this possible to preload Fragments for ViewPager so that there's no lag when user swipes to next page?
Sure. Have your adapter preload the fragments. You are responsible for returning fragments in getItem() -- whether those are "preloaded" or not is your job.
That being said, your problem most likely is not with the fragments themselves, but something that the fragments are doing. For example, you "got a lot of bitmaps to load in my pages", and if you are doing work related to those on the main application thread (e.g., using BitmapFactory), you are causing your own lag.
So, instead of racing off to "preload" stuff, a talented programmer would find out specifically what is causing the lag, using tools like Traceview. Then, and only then, would a talented programmer start working on a fix.
I'm using FragmentPagerAdapter with a tabbed interface. My interface happens to have three tabs. I can see that as soon as my app is created, the adapter requests that both tabs one and two both be created immediately (I assume this is so swiping to the next tab appears smooth to the user).
Is there a way to stop the automatic loading of the next tab? My tabs are pretty heavy, and loading two right at startup is taking a good deal of time,
Thanks
Is there a way to stop the automatic loading of the next tab?
Sorry, no. This is driven by setOffscreenPageLimit(), and the minimum value is 1, meaning that ViewPager will always try to create and hold onto at least 1 page on each side.
It sounds like you need to move more logic into background threads.