I have a problem with the viewpager navigation. It hangs during the transition from one page to another. (Laggy). You can see above the simplified architecture of my code. I understood that AsyncTask were the problem since these processes communicate with UIThread. My asynctaks update fragment views. So, is it possible both to navigate very smoothly with viewpager and simultaneously update views?
Thanks
Hard to give a specific answer without seeing your code, but :
AsyncTask are only supposed to touch the UI thread in the onPostExecute method, and that should be used to update your UI once the task is complete. You should set a default UI to be shown as soon as your Fragment is created and update the UI when the task is complete. If you can't show any content before getting data from the AsyncTask, you can set the Fragment's view to show a ProgressBar and hide that to show your data when you have it (refer to this question for details).
I hope this helps ;) Let me know if you need more explanation ...
Related
I am working on an Android app that uses 5 ActionBar tabs to navigate between different pages/fragments.
Problem is, that the navigation between the fragments is causing the UI to hang/flicker.
The UI of the fragments is not dynamic, meaning that it is not build with a static set of controls. When a fragment becomes visible apps starts to load the corresponsing view model, e.g. by loading a set of data from a server. As soon as the model is loaded the UI is generated. Thus showing a fragment includes the following stepps:
Show an inderminante progress bar to indicate the running progress
Start an AsyncTask to do the heavy loading
As soon as the task is complete generate the UI, e.g. insert an ImageView for every loaded image.
Hide the progress bar and show the generated content.
I thought using a background thread to do the loading would avoid any UI hangs but this it not the case. The creation of the UI elements has to be done in the UI thread of course and it seems that this work is causing the UI hangs.
Even if the number of UI elements that have to be create is quite low (e.g. create 10 Buttons) the UI hangs for a moment. Thus using other strategies (e.g. create visible elements only) does not solve the problem.
Only when no UI elements are created at all the navigation between the fragments runs fluently.
How can I solve this?
The only solution I found so far is, not to load the view model / generate the UI when a fragment becomes visible / is created but as soon as the activity is created. In that case I would only show the activity once the view models / views of all fragments have been loaded/generated. But this would mean to load a lot of data without knowing if it will be used at all.
Is there any better solution? Creating UI elements on the fly is not that uncommon, is it? Thus there has to be a way how this can be done without blocking the UI.
I have covered with Swiping problem. I have 3 activities and each activities is using downloading data from server. I want to make them smoothing horizontal scrolling as swiping.
i used to view pager and fragments but not got good solution.
please any one help
Use view pager for three tab and download the data on MainActivity using AsyncTask. After each download finished, update fragment by callback interface. You can also store data in Application class to persist it through all the application.
All the downloads should be performed at background
Use handler to update fragment UI
You could cache the root view of Fragment.onCreateView(), like the way you did in ListAdapter.getView()
In my Android project I have an Activity that uses a Master-Detail view, created with two fragments.
My detailfragment is giving me some "problems" though.
It consists of 50+ controls (TextViews, EditTexts, CheckBoxes, Spinner). Of this 50+ controls I programmatically get a reference to 32 of these controls in my detail-fragment and load their data from my SQLite database.
When I run this and initialize my controls by using
(SomeControl).findViewById(R.id.mycontrol);
LogCat keeps warning me about that I might be doing too much on the main thread.
I know that findViewById and inflating views is an expensive operation, so I had an idea!
I was wondering if there was some way to use the viewholder pattern or view-recycling on my detail-fragment like I'm doing on my ListFragment. that way I could avoid reinitializing my detailview each time I select another item in my ListView. And avoid calling .findViewById as much as I do. Does anyone have an idea on how to implement something like this. Would it make any difference if I did initialization of the controls in the onCreate-method of my detailsfragment? I was also thinking about making my detailsfragment a "singleton" and then just use getLoaderManager().restartLoader when the selection of my listfragment changes. Any thoughts on all of this would be very much appreciated.
Well unless you're using the exact same layout for each control then I'm not sure if there's a way to do that.
But there may be a way to solve your problem: using an AsyncTask.
As long as those controls aren't necessary for your program to crunch data (and from your explanation I don't think the UI elements would be triggered until the user has interacted with it) you should be fine and the main thread will be free to do whatever it needs. The only downside I see with this method would be that some UI elements might appear maybe a half a second late (not so bad if you think about it).
Found a solution. Had to change my implementation entirely though.
Now my implementation is using loaders on both ListFragment and DetailFragment.
Here's a list of changes I've made:
Created a interface for my ListFragment with one method (onSomethingClicked(SomeObject obj)) and made ListFragment observable through this interface.
Implemented the interface in my DetailFragment and registered a listener on the ListFragment.
Implemented the method onSomethingClicked() in DetailFragment. When this is triggered i pass data from ListFragment to DetailFragment and restart my DetailFragment-loader and load data into my already initialized controls in OnLoadFinished.
No need to inflate the view every time the selection in the list changes and no need to .findViewById's AND MOST IMPORTANTLY no more Choreographer warnings :)
I am trying to update my listfragment when a button is pressed. the button puts a name into a database but how do I update the list so that name appears? the listfragment uses a cursorLoader to load from the database. I even tried using a content observer on the database and calling getLoaderManager().restartLoader() but that didnt work either.
So what can I do to update the list when I click a button in an activity? I have found very little information on this please help
I can't be sure, but I assume there is something weird going on with the interaction between your Fragment and your Activity, which you are apparently displaying simultaneously somehow. Is there any reason why you are listening for the Button in the Activity? Are you dealing with a multi-pane screen or something? It seems like it'd be a lot simpler to just have the Fragment deal with this itself (since it is the one implementing the LoaderCallbacks, I assume).
Also, be sure that you are implementing your Fragment lifecycle correctly... i.e. you call initLoader() and set the list's adapter in onActivityCreated() as opposed to onCreate().
Hope that helps!
I want a Viewpager that shows loading while content is coming in from the background. Basically I expect the first View to be loaded, but View+1 and View-1 will still be loading. If the user swipes to either side I want them to be presented with a spinning dialog while it loads
Would I just add AsyncTasks into the ViewPager with some conditions determining when they will run? I dont want too many AsyncTasks to be loading as the viewpager will have many views off to the sides.
I think the Trulia app does this, it is similar to what I am looking for. Apartment image viewing shows a loading screen while the images are loading in that viewpage.
Also for the record, can I just treat viewpagers like onCreate functions of an activity? That would really clear things up
Insight appreciated
Have a look at the supplied FragmentPagerAdapter if you want to perform more Activity-like lifecycle management of each page.