I have a activity (Activity A) with a fragment that has a ListView inside of it and I'm calling another activity (Activity B) to add records to the fragment's list.
My problem is that calling adapter.notifyDataSetChanged on Activity A's onResume/onFragmentResume and the fragment's onResume changes nothing.
My adapter is populated in Activity A's onCreate.
I also tried inserting the adapter.notifyDataSetChanged in a runOnUiThread.
Any one tackled this situation before?
It is not a good suggestion but try to reinitialize the adapter and set it again and tell me if it is work fine.
You should populate your adapter in the fragment in either the onAttach(), or onViewCreated() methods. You could also populate it in the onCreate() of the fragment, then call notifyDataSetChanged in either of these lifecycle methods I suggest.
These methods will be called whenever the fragment is connected and drawn, thus, you can be sure that it will populate your Fragment correctly.
In general, have all your view related items (like adapter creation and population) in your fragment, and navigation (ActionBar, and flowing between Activities) in your Activity.
Related
I have an activity with fragment A. Fragment A hosts a list in recyclerview which requires an adapter. When an item from the list is clicked I want to open another fragment, say B, showing additional details about the item.
I can open fragment B in three ways:
From the recyclerview adapter itself where I will have the item position etc.
From fragment A using callback from the adapter, since the adapter has all the required info like position, object etc.
From the activity, again using callback. If i do from the activity, i will have to add callback interface from adapter to fragment A, and finally to the activity. Looks too much.
I want to know what is the best way to open fragment B.
Hey its not good practice to start the fragment from adaptor. because it will be very complex to find the container of fragment. so please always try to start the fragment from main activity which will be parent of all fragment.I hope its help you.
Option 2 is always good approach->
2. From fragment, A using callback from the adapter, since the adapter has all the required info like position, object etc.
"According to MVC pattern adapter is always used for binding view with lists. So adapter should always independent from the fragment so the Single Responsibility Principle will always be handled. So, there should be no dependency from the adapter to fragment but fragment to the adapter. When you call fragment or activity from adapter it will create a cyclic dependency with one another so memory will not clear until you finish the apps. You can call any callback method of the fragment from the adapter which method will call the desired fragment you want."
I have main activity with list of fragments to dynamically add/delete them. When I create new fragment and put it to my list, onAttach() ,onCreate(), onCreateView() methods are called. But if I remove this fragment from list and then create new one, this methods are not called. Can anyone explain me why? Thanks in advance!
When viewpager displays one fragment, it will automatically load the fragment pages around it for performance reasons.
In my fragments, i have recycleviews with a popup menu to delete one item in the list.
I am facing a problem of deleting one item from one fragment, but that item still exists in the other preloaded fragments after I scroll to them.
It works only if I force the viewpager to reload the contents of its fragments by manually scrolling back and forth the fragments.
Is there a way to force reload the preloaded fragments by viewpager?
Your problem can be solved by using Interface. Google suggest using callbacks\listeners that are managed by your main Activity for communicating between fragments.You can use Interface which tells the other fragment to refresh its listview when you delete an item in current fragment.
For an overview http://developer.android.com/training/basics/fragments/communicating.html
Also a good question about this How to pass data between fragments
First create an interface to detect changes in your RecyclerView:
public interface MyRecyclerViewChangeListener(){
void onRecyclerViewDataChanged(int id);
}
Create a static variable in your Fragment or Activity which contains your viewpager:
public static List<MyRecyclerViewChangeListener> mListeners = new ArrayList();
Implement your interface to your ViewPagerFragments and do what you want in method you implemented.
In your fragment's onResume register your listener to mListeners like blow to detect changes:
MyFragmentOrActivity.mListeners.add(this);
And in your fragment's onPause unregister your listener:
MyFragmentOrActivity.mListeners.remove(this);
Finally notify your listeners when your recyclerview data changed:
for(MyRecyclerViewChangeListener listener : mListeners){
listener.onRecyclerViewDataChanged(id);
}
Edit : If you are changing your recyclerview's data after an async task result such as a web api call, you can register your listener in fragment's onCreateView method and un register in onDestroyView method. So you can catch changes in your fragments.
I am not sure if i'm getting your question right but i think this should do it.
YourViewpager.setOffscreenPageLimit(0);
Now the fragment should be destroyed if it is not active and will be recreated if you open it again.So the data change should be recognized.
Hope I could help
Try setting mViewPager.setOffscreenPageLimit(1) such that it will not pre-cache any fragment or you could use FragmentStatePagerAdapter inside viewPager to achieve what you want.
Edit 1:
So Conclusion is :
1) Use local broadcast mechanism to update the fragments present in ViewPager adapter
2) Use handler mechanism to refresh these fragments
3) if you want to blindly update these fragments once they are visible to users then do it inside onPageChangeListener of view pager method.
The answers helped me find the solution.
For future reference, I used a callback every time I used deleteItem(), and took a list of the loaded frags by using the method [FragmentHostingViewPager].getChildFragmentManager().getFragments()
Then I iterated through each fragment as long as each fragment was not null, and called a refresh() method on them.
I have a custom ListView inside a fragment that represents a list of activities. Each activity is saved in a database (I'm using Parse), and the ListView is populated with the Activities from the database. There is an add button in the fragment that takes the user to an screen where he/she can create a new Activity object. When the user is done, the activity is finished (I call finish() on the Activity), and the fragment is brought back up. The problem is that the ListView doesn't refresh- it's the same list before the user was sent to the Activity Create screen.
I tried to override the onStart and onResume in my fragment class and call notifyDataSetChanged() or invalidateViews() but neither method works, the list view doesn't refresh so it includes the new Activity that was just created by the user.
Start the activity that adds Activity with startActivityForResult(). Override the onActivityResult() in your listview fragment to get notified when the user has finished adding an Activity. Then, refresh your ListView by querying the database again or adding the new Activity to the adapter (depending on how you implemented the listview adapter).
In your case it looks like you forget to refill the activity list attached to adapter from which listview generate views.
Refill the list again from scratch and then call notifyDataSetChanged();. Your listview will be updated with new entries.
Cheers
I have Fragment which I replace by another one. I put transaction to backstack so I can move back later. If I press back button saveInstanceState Bundle of restored Fragment is null in it's methods cause saveInstanceState method of Fragment is actually called when parent Activity instance destroyed. So how I must restore Fragment state after returning it from backstack?
This problem was mostly related to ListViews. I have found a solution in more correct managing of adapter data. I had local mAdapter variable in my Fragment which was created, populated with data and set to ListView in onResume() method of my Fragment. I have found solution in moving this code into onActivityCreated() method.