FragmentStatePagerAdapter does not retain its state when back to parent fragment - android

I'm making a view whose architecture is:
A fragment has view pager that has FragmentStatePagerAdapter(adapter 1), FragmentStatePagerAdapter (adapter 1) returns a Fragment when click on Fragment it opens another Fragment that again has a ViewPager and FragmentStatePagerAdapter(adapter 2) attached to it that again returns a Fragment.
My problem is when I'm clicking on Fragment and returning by pressing back button the Fragment is blank, also when I'm using getChildFragmentManager on adapter 1, application crashing that no view found for Fragment.
Edit:
by debugging I found that FragmentStatePagerAdapter wont return fragment that was returned previously thats why I'm getting blank page
In a fragment:
viewPagerDetail.setAdapter(new ProductDetailViewPagerAdapter(getFragmentManager()));
tabLayoutDetail.setupWithViewPager(viewPagerDetail);
(if I'm using getChiildFragmentManager here it crashing application)
Inside ProductDetailViewPagerAdapter:
#Override
public Fragment getItem(int position) {
return new ViewPagerImageFragment();
}
Inside ViewPagerImageFragment: there is single imageview when I click on image view it opens a fragment that has viewpager that has adapter attach on it that also returns a fragment when I press back to fragment that has ProductDetailViewPagerAdapter the viewpager is blank

For the fragment like these kind of nested, we should see for hierarchy of the fragment either we want to see parallel or step ahead or below for step ahead or below choose getFragment manager when replacing and
getParentFragment().getFragmentManager()
for parallel fragment replacement
Happy coding!

Related

Fragment displays wrong menu items

For unknown reason sometime my fragment is showing menu items that belongs to a different fragment.
I have a single activity with custom back stack to maintain the correct flow using:
Map<Integer, List<Fragment>> fragmentStack = new HashMap<>();
This way each "tab" has its own backstack.
I am switching between the fragments with:
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment)
.commitNow();
The fragments are maintained in the Map, so when switching to existing fragment I use it's already initialized view.
Sometimes when I switch from one fragment to second fragment, the second fragment displays menu items from a previously created fragment in the stack despite the fact that onCreateOptionsMenu is called correctly on the second fragment. How do I overcome this unwanted behavior?
The actions that lead to this behavior:
1. Starting at first tab. Map initialized at key 0, with List<fragment> with one fragment, called A. This fragment then displayed. (fragment A has menu items) 2. Navigating to second tab. Map initialized at key 1, with List<fragment> with one fragment, called B, this fragment displayed (replacing fragment A). Fragment B also has menu items. 3. Navigating back to first tab. Previous fragment A is used including it's already initialized view (not inflating a new one). 4. Clicking something with navigates to a new fragment C staying at the same tab. fragment C is added to the fragment list, under the key 0 of the Map. fragment C has no menu items.
5. Navigating to second tab. Previous fragment B is displayed but with menu items of fragment A!
check onCreateOptionsMenu is called for all fragment or not.
I found the problem eventually.
The fragment's onCreateView looked this way:
if (rootView == null) {
// Init view logic and inflation, and:
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
}
return rootView;
moving the ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); outside the if statement fixed the issue.

How to refresh fragment from base fragment

Sorry for bad English.
I have BaseFragment. it contains Search View and View Pager and View pager has three fragement like Fragment A,B,C
Fragment B has Listview.
so whenever i am doing search i got search response in Base fragment now what i want to do is push these response to fragment B listview inside viewpager. when every time search action perform and need to refresh listview.
You can get an instance of the fragment you want by calling Fragment manager like this:
CustomFragment fragment = (CustomFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_a);
and then you can call any methods of the fragment like this:
fragment.update(data);
But make sure you check the fragment is not null before calling its methods.

Can I add a fragment to a FragmentActivity outside of whats in the viewpager?

I'm new to fragments. I have an activity that extneds FragmentActivity and uses the ViewPager to swipe between fragments.
Within one of the fragments I want to launch a new fragment that is "outside" of whats in the view pager. Is it possible to add a fragment like this or do I need to start a new activity with the fragment.
Now I have it launch a new activity but it is very slow.
Activity A
Fragment A
Fragment B
Fragment C
Activity B
Fragment D
Fragment A
So fragment A can launch acitvity B to get to fragment D but ideally it would be cool if I could just inject fragment D in Activity A
Hope that makes sense.
Yes, you can, but I strongly suggest you avoid it, unless you have a good reason to do so.
The ViewPager is (I assume) hosted in your Activity. The ViewPager obtains its views from its adapter. (A FragmentStateAdapter or similar). So you could tell the activity to change its layout (and or hide the Viewpager and show another FrameLayout) or you can simply launch another Activity that contains a single fragment. This is also fine.
Messing with the ViewPager/Adapter is usually complicated and you may waste time trying to make it work.
On the other hand, you could add the Fragment to the ViewPager's Adapter and use the getType of the adapter to return a different type of Fragment.
So you could do (pseudo code):
mPagerAdapter.addFragmentDToTheDataAtPositionZero(); //longFancyName ;)
mPagerAdapter.notifyDataSetChanged();
mViewPager.setCurrentItem(0, false);
that'd add Fragment D to the "top" of the viewpager and will switch to it.
Your Adapter then has to use an Interface to determine what type of fragment must be instantiated…
The getItem of the adapter would look like… (again, pseudocode)
#Override
public Fragment getItem(final int i) {
final FragmentTypeInterface f = yourData.get(i);
if (f.isD()) {
return FragmentD.newInstance();
} else {
return OtherFragment.newInstance();
}
}
And so forth… :)

ViewPager with Fragment reload at first and last page

I'm trying to create a ViewPager with six fragments but only 2nd fragment to 5th fragment contain data that I want to show and the first fragment and the last fragment I want to be used to reload the data and set the position to the 2nd fragment again. The overall flow is like this :
1st (reload and go back to 2nd) <- 2nd fragment <-> 5th fragment -> 6th fragment (same with 1st)
what I've tried is I create a callback from the 1st fragment and 6th fragment like this
public static class callbackFragmentLoading implements callbackFragmentLoad {
#Override
public void onLoading() {
mPager.setAdapter(mAdapter);
mPager.setCurrentItem(2,false);
}
}
and I passed the callback to the fragment constructor so I can called the onLoading function in the onActivityCreated. But I everytime I do it the application will be force closed and the logcat shows
recursive entry to executependingtransactions
is there any way to do this? or my method for doing it is wrong?
Thank You
is there any way to do this? or my method for doing it is wrong?
Messing with callbacks between Fragments of a ViewPager isn't probably such a good idea. Instead I would do it like this:
Don't load any data(like with a Loader) in the Fragments from the ViewPager, instead let the FragmentActivity do it(and the Fragments will get it through methods from the Activity).
Your two loading fragments(position 0 and 5) will call in their onResume method a reload action on the parent Activity(like a Loader restart)
At this moment the Activity will load/reload the data and when that finishes it will set the ViewPager to the correct items(either 1 or 4)
in the onResume method of the data fragments you'll refresh the fragment's data(here you may need to use some sort of signaling system because you'll need to duplicate the refresh code in the onCreateView(some fragments may have their view destroyed if they are far apart from the current visible position)).
As I don't know many things about the inner data fragment I've written a basic skeleton sample(without the data loading in the activity).

ViewPager + FragmentStatePagerAdapter : need to know when fragment is displayed (selected)

I am using a ViewPager plugged to a FragmentStatePagerAdapter. Each fragment contains a listview. In this listview I wish to display ads and make calls to a analytics server. I only want to make those calls when the user navigates to a fragment (so I cannot use the onCreateView or onActivityCreated events in the Fragment). Is there an event I can hook on to this end ?
Update
I realized that the way I am fetching my current fragment is flawe
#Override
public void onPageSelected(int page) {
this.currentPage = page;
tabsAdapter.getItem(page);
}
getItem(int position) in the pager is actually responsible for instanciating the fragments, so it would create a new unattached fragment (hence getActivity() returning null). I think I will us an approach where I keep a map of the fragments (<Position, Fragment>), i will remove the fragment from the map when destoryItem is called in the pagerAdapter.
You are right, best option is the second solution here:
http://tamsler.blogspot.nl/2011/11/android-viewpager-and-fragments-part-ii.html
so your thoughts are correct.
How about this:
http://developer.android.com/reference/android/support/v4/view/ViewPager.OnPageChangeListener.html
The onPageSelected(int) method sounds like it does what you want.

Categories

Resources