I have a FragmentStatePagerAdapter, and it have a lot of "pages", that may be added or removed by the user.
When an page gain focus, it have to load it contents from the database.
My problem is when the adapter have 2 pages or more , and add a new page i have to call notifyDataSetChanged who reload all "pages"(fragments), and the application begins to run slow.
There a way do add and remove content to an adapter without calling notifyDataSetChanged ?
i found the awnser here:
Make sure your ViewPager declaration has not a layout_width="0dip".
FragmentStatePagerAdapter instanciates all fragments after updating to ADT 22
Related
I'm a newbie to android app dev and I have one little problem. I'm developing a note app with a single activity(MainActivity) which has a NavHost and host three fragments(NewNoteFragment, NoteListFragment and NoteUpdateFragment). The note details are stored in a sqlite database.
Whenever user creates new note or update the existing note, the changes can only be stored to the database in NewNoteFragment or NoteUpdateFragment's onPause override i.e when the user navigates from the said fragments to the NoteListFragment. Although the changes were saved but the recyclerView in the NoteListFragment doesn't update immediately until i kinda navigate away from the NoteListFragment to other fragment.
When I check the logcat i noticed the onResume override(which is where I called my adapter.notifydatasetchanged() method) in my NoteListFragment is called before onPause override of the replaced fragments.
Is there a way to change the fragments navigating behaviour where onpause is called before the onresume? Or any better way to achieve my said aim.
You cannot set onPause to be called before. Since you are using fragments try to update the recyclerView onViewCreated() function of Fragment.
You cannot change the Android Lifecycle, it is always set.
I would advise using Room and LiveData, any changes in the database would automatically update the RecyclerView you mentioned.
You can read more about live data here
I have an Activity with a Fragment that displays a ListView containing simple TextViews. A menu item can trigger another Activity via an Intent. That new Activity clears the ArrayList underlying the ArrayAdapter for the ListView using ArrayList.clear().
When I backup from the new Activity to my original one with the ListView, and get control in onResume(), I find that my ListView.getChildCount() is the same as when it was left due to the Intent, but the ListView.getCount() is now properly zero!
I have tried using the adapter's clear() method, I have tried Adapter.notifyDataSetChanged() (although I should not have to).
If I modify the underlying ArrayList from within the fragment itself, all seems fine. For example, clicking on an element gives you an option to remove it, move it up or down, etc... That works OK.
Also, If I then leave the List Activity and return to it again, all is well. So clearly the ArrayList is the same list. I never create a new list, only .clear() it.
Any idea how the Child Count can possibly be more than the underlying element count? Perhaps some kind of observer for the ArrayList does not trigger because the Activity is suspended? In which case how could I sync them up again? I have tried invalidate() for example.
This is under API 23.
I seem to have found a workaround. I noticed another post here discussing thread safety. It seemed to have implications if you do not modify your list from the original UI. So, in my onResume(), I just did a setAdapter() again. With the same adapter and list, and viola! All seems well again.
When I add page after current page, and flip to it, I see not added page, but cached page.
Is this possible recache pages manually after adding new page if new page is near current page?
P.S. notifyDataSetChanged() in adapter doesn't help.
I apologize as I can't comment so this will have to do as an answer:
This will depend on the adapter you wrote or are using, and the exact method. Namely, if you were using a customized adapter with the appropriate overridden methods [which would be best for anything fairly complicated like this]:
When you add the new fragment/page, add it to the internal list within the page [which should work naturally with the other overridden functions, including getCount()]
Make sure to set up the fragment appropriately and implement its lifecycle accordingly so its data changes. [Ie, this is a possible source for your bug if you're using an adapter] If you merely used the onCreate and other basic lifecycle functions, then it may be an issue where the lifecycle method already occurred so the changes won't be taken place [Possible solution: call a function in this case]
That's the basics of the issue. Without any code for the adapter and how+where it's being used, I can't say much else. Hope this helps.
I have a ListFragment whose data is populated by a custom adapter ( a SimpleAdapter in my case). I was experiencing issues with using notifyDataSetChanged() from within my class that extended ListFragment. After a lot of looking around and several (useful) Stack Overflow posts later:
listview not updating with notifydatasetchanged() call
Android ListView not refreshing after notifyDataSetChanged
adapters notifyDataSetChanged does not work
notifyDataSetChanged not working
ListView does not update when calling notifyDataSetChanged from a BaseAdapter
I understand that a loose (and highly un-recommended) workaround would be to re-set your adapter using setListAdapter(). However I am now facing issues with this as well.
The documentation, http://developer.android.com/reference/android/app/ListFragment.html#setListAdapter(android.widget.ListAdapter), mentions that setListAdapter()
Provides the cursor for the list view.
But I still have some questions.
Q1. Does initializing an adapter multiple times using setListAdapter() 'point' to the same adapter instance ?
Q2. What actually happens when a call is made to getListAdapter() and then to notifyDataSetChanged() when an adapter has been set multiple times using setListAdapter() ?
Q3. This question is based on an assumption from Q2- when notifyDataSetChanged() is called when an adapter is set multiple times, which of those adapter instances (this part is the assumption), if they exist' is actually being notified for change ?
I am a beginner with Android and I believe there a quite a few nuances I do not understand.I would be extremely grateful if you could clarify these questions. Also thank you very much for your time.
Q1. Does initializing an adapter multiple times using setListAdapter() 'point' to the
same adapter instance ?
Ans: Initializing the adapter will point only to the last instance that you set using setListAdapter.
Q2. What actually happens when a call is made to getListAdapter() and then to
notifyDataSetChanged() when an adapter has been set multiple times using
setListAdapter() ?
Ans: It doesn't matter how many adapters that you have initialized, only the last instance will be retrieved using the getListAdapter().When you use notifyDataSetChanged() only the last instance wich is retrieved using getListAdapter() will be refreshed i.e. ; the last instance will be reloaded(By calling the getView).
Q3. This question is based on an assumption from Q2- when notifyDataSetChanged() is
called when an adapter is set multiple times, which of those adapter instances (this
part is the assumption), if they exist' is actually being notified for change ?
Ans: The above answer contains the explanation for this.
I identified a problem in changing one activity using tab. In one tab activity I'm adding data to my SQLite database, and in the other tab activity I am displaying them using listview(array adapter). But when I come back to add data after adding new items to SQLite, the newly added records are not updated in my listview.
How do I fix this?
You seem to be pulling the list data from a DB. Is there a reason why you are using an ArrayAdapter instead of a CursorAdapter?
Anyway, you should call notifyDataSetChanged() on your list adapter when the data has changed so it can refresh the view.
you can add code to update your listview (via notifyDataSetChanged or some such) by overriding the onResume() method in your activity which is called whenever the activity is brought back to the foreground.
See http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle