I have a simple activity with two fragment: main (contains a list of items) and detail. Details screen is a fragment, which is displayed when an item is clicked in main list. DetailFragment is being shown using replace().
After navigating back from detail screen I would like to have exact same scroll position in RecyclerView that I left it with.
As long as replace() initiates onDestroyView() and onCreateView() cycle to happen for MainFragment, after coming back from DetailFragment the RecyclerView has a scroll position of 0 (at the top), because this is a brand new RecyclerView which has no connection to the one that was there before leaving to DetailFragment.
replace()ing fragment does not initiate onSaveInstanceState() to be called, that's why using techniques outlined here are not applicable.
I wonder what is the correct way of handling this use-case?
Of course I can save the position on onDestroyView() and later manually scroll to that position, but maybe I'm missing some obvious solution?
An answer, that will propose to use add() instead of replace() is not welcome.
I've had RecyclerView declared as a child of NestedScrollView. This was the issue.
When I got rid of NestedScrollView everything was handled automatically.
As onSaveInstanceState() is not possible, try using ViewModel to save the required data.
When you declare and set the adapter to your first recyclerview, try having a call back to your actvity passing the adapter instance , where in your activity you can try saving the adapter instance or any required data in the ViewModel of your activity.
Once you come back from your details fragment you can get the saved instance of your reycycler data from the activity`s ViewModel.
Related
I have 3 fragments in the ViewPager.
PersonalFragment
CropFragment
NotesFragment
Every fragment has a RecyclerView and I was adding items using a dialog in it. However, when I go to the last fragment (i.e. NoteFragment), the first fragment's (i.e. PersonalFragment) RecyclerView gets empty (all items are removed). The same thing happens when I come back to the first fragment, the last fragment's RecyclerView resets (all items are removed).
It is difficult to understand without seeing some of your code which is related. I think you might have implemented the onResume function incorrectly. Each time you go to the third fragment in your ViewPager, the first Fragment needs to be reinitialized and you need to take care of this in your onResume function.
However, another workaround for your problem is setting the off-screen page limit of the ViewPager like the following.
viewPager.setOffscreenPageLimit(2);
Hope that helps.
I have a Fragment, that I replace with a transaction with a new one
That Fragment contains a RecyclerView with a big number of items.
When the user presses the finish button on the new fragment I pop the backstack, and the old fragment is recreated.
This causes the OnCreateView method to be called again and everything works fine with that.
My problem is that the RecyclerView in it is recreated, the adapter is reset, but it seems to automatically move to the position that it left (which I assumed would only happen if I used transaction add not transaction replace)
As a side note the adapter still calls OnBindViewHolder and OnCreateViewHolder for the visible items.
My question is , why does this happen? since the whole fragment is recreated shouldn't it reset to the first position? Other than manually calling scrollToPosition(0) before loading the new fragment, is there another way to make the fragment not remember anything and be actually fully recreated when returning ?
The LinearLayoutManager stores the scroll position in onSaveInstanceState. Since the SavedState parcelable is stored with the view id, as long as the position is not out of bounds while returning from the backstack, the scroll position is restored.
I am using a recycler view to show some items, everything works fine but when I open another fragment and then reopen the fragment having recyclerview. it doesn't show anything.
Can somebody tell me what is its cause?
You should have a look at the lifecycle of a fragment.
It seems your code for filling the recyclerview with data is in the wrong method.
Lifecycle methods like onCreate(), onCreateView() etc. are just called on creating the fragment.
if you leave the fragment (and do not finish() it by yourself), it won't be destroyed so these methods are not called again.
You need to fill your recycler view in onResume() method
I have an android app in which I want to dynamically add and remove Fragments to a ViewPager during runtime, and preserving the Fragments on configuration changes.
Thus far I have implemented a FragmentStatePagerAdapter, holding my Fragments in a list with methods add, remove and replace to manipulate my Fragments. Basically, all they do is insert or delete a Fragment in the list and then call notifyDatasetChanged(). I insert the staring Fragment as a new Fragment during the Activitys onCreate() method.
I know want to preserve my Fragments during configuration changes. Currently, when I change my screen orientation, all my currently Fragments are deleted, and I get back to the starting Fragment, naturally because the Activity is recreated, and the Fragment and the Adapater are reinstantiated during the onCreate() call. I was trying to save the state of the Adapter with the Adapter.saveInstance() during the Activitys onPause(), but when I try to restore it via Adapter.restoreInstance(), I get an empty adapter.
Can anyone give me a hint on what is the correct way in Android to save state a FragmentStatePagerAdapter?
To save the state of the current fragment, i think first of all you will have to check which fragment is currently added/visible in the container activity. Once you have that fragment, simply use onSaveInstanceState() method of the container activity to save the instance of the current fragment.
For code snippet please follow this link.
I have a ViewPager. It has Fragments. When those Fragments are created, they load data from the server. When the user selects a menu item, I want to tell those fragments to filter their data without reloading from the server.
To do this, I have a subclass of FragmentPagerAdapter which keeps a List to hold a reference to each Fragment as it is created. When the menu item is selected, I simply iterate over that collection and call a method on each Fragment.
The problem arises when the device is rotated. The framework automatically restores the fragments to their parent view, without calling the getItem method of my adapter, meaning that my List is empty.
How can I either repopulate that List when the device is rotated, or obtain a list of all of the ViewPager's child Fragments without keeping a list?
EDIT: It may be important to note that my ViewPager lives in a Fragment, and that Fragment gets hot swapped via a side navigation menu. In other words, my ViewPager is not owned by an Activity, and there are some known issues about ViewPager not cleaning up its child fragments correctly which may be exacerbating the problem.
Check this link Get Current visible fragment in ViewPager
The author basically suggests 2 similar approaches which are to attach tags on fragment creation and keep track of it.
getSupportFragmentManager().beginTransaction().add(myFragment, "Some Tag").commit();
Then retrieve the tag like so:
int index = mViewPager.getCurrentItem();
String tag = mPageReferenceMap.get(index);
Fragment myFragment = getSupportFragmentManager().findFragmentByTag(tag);