问题
I got a FragmentPagerAdapter. It's getItem
method can return a fragment according to data it has from the outside. After I update the data its suppose to display I call notifyDataSetChanged
and yet nothing happened. I DID override the getItemPosition
method to return POSITION_NONE
:
public static class TabsAdapter extends FragmentPagerAdapter implements TabHost.OnTabChangeListener,
ViewPager.OnPageChangeListener
{
private final Context mContext;
private final TabHost mTabHost;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private PagerTabsFragments fragmentDisplayInfo = null; // for now only a
// single size
// back
// stack
static class PagerTabsFragments
{
public int tabPosition;
public Fragment fragmentToDisplay;
public Object fragmentInfo;
public PagerTabsFragments(int tab, Fragment frag, Object info)
{
tabPosition = tab;
fragmentToDisplay = frag;
fragmentInfo = info;
}
}
public void SetFragmentToDisplay(int tabPosition, Fragment frag, Object info)
{
fragmentDisplayInfo = new PagerTabsFragments(tabPosition, frag, info);
notifyDataSetChanged();
}
public void CancelFragmentToDisplay()
{
fragmentDisplayInfo = null;
}
...
@Override
public Fragment getItem(final int position)
{
if ((fragmentDisplayInfo != null) && (fragmentDisplayInfo.tabPosition == position))
{
return fragmentDisplayInfo.fragmentToDisplay;
}
final TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
@Override
public int getItemPosition(Object item)
{
if (fragmentDisplayInfo == null)
{
return super.getItemPosition(item);
}
return POSITION_NONE;
}
...
And the update from outside is in a click event which sets the fragmentDisplayInfo
var.
I debuged and saw that the fragmentDisplayInfo
is indeed initialized and the getItemPosition
method does return POSITION_NONE
, but the getItem method is not even called. Why is that?
EDIT:
If you hadn't done so as well, please notice that overiden part of the adapter:
@Override
public int getItemPosition(Object item)
{
return POSITION_NONE;
}
回答1:
I'm not sure about this, but you can try to use FragmentStatePagerAdapter
instead of FragmentPagerAdapter
. The thing is, i've also run into this issue, and it helped me
回答2:
What Nik Myers is saying is correct. However there is a piece missing. When notifyDataSetChanged is called, the method getItemPosition is called. You need to override this to get the fragments to reload.
@Override
public int getItemPosition(Object object) {
// Causes adapter to reload all Fragments when
// notifyDataSetChanged is called
return POSITION_NONE;
}
回答3:
I have faced the similar problem when I was working on my last project. So I found few Solution.
by overriding getItemPosition in the pager adaptor but this is not a good idea.
@Override public int getItemPosition(Object object) { // it will recreate all Fragments when // notifyDataSetChanged is called return POSITION_NONE; }
The second one is cabezas Solution.
Most Stable solution override getItemPosition in below fashion:
@Override public int getItemPosition(Object object) { if (object instanceof MyFragment) { // Create a new method notifyUpdate() in your fragment // it will get call when you invoke // notifyDatasetChaged(); ((MyFragment) object).notifyUpdate(); } //don't return POSITION_NONE, avoid fragment recreation. return super.getItemPosition(object); }
回答4:
none of the solutions given above works for me. So hope below solution may be helpful for you.
In my code, I have 2 Fragments in viewPager. One is used for 3 EditTexts and 1 button and another fragment has RecyclerView. On button click, my value is going to recyclerView, but it's not updating. So now, I used the below code:
I called the notifyDataSetChanged() on button click. My MainActivity has inner adapter class extends FragmentStatePagerAdapter class. So i called it using mainActivity.mMainAdapter.notifyDataSetChanged(). Hope it helps someone.
回答5:
Every answer here did not work perfectly for me but combining multiple answers into one is right choice.
public final class SomeFragment extends FragmentStatePagerAdapter{
private final List<Fragment> fragments;
private Fragment removeFragment; //Fragment to be removed in the next notifydatasetchanged
@Override
public int getItemPosition(final Object object) {
return object.equals(this.removeFragment) ? FragmentStatePagerAdapter.POSITION_NONE : this.fragments.indexOf(object);
}
}
Return POSITION_NONE only for the fragment you would like to remove from the viewpager. Every other fragment is still in your fragment list. Do not forget to remove the "removeFragment" from the list before calling notifyDataSetChanged();
来源:https://stackoverflow.com/questions/30080045/fragmentpageradapter-notifydatasetchanged-not-working