Android ViewPager会替换当前片段,但向后滑动时,初始片段不会';t被重新加载

Android ViewPager会替换当前片段,但向后滑动时,初始片段不会';t被重新加载,android,android-fragments,android-viewpager,swipe,Android,Android Fragments,Android Viewpager,Swipe,我的问题是我有一个ViewPager,它显示4个片段(比如:a、B、C、D)。但有时当用户单击某个东西时,我需要用另一个片段(比如E)替换它,例如A。我通过重写getItemPosition并在我的ViewPager中编写一个自定义的setCurrentItem方法来实现这一点。以下是我的课程: MyFragmentStatePagerAdapter: public class MyFragmentStatePagerAdapter extends FragmentStatePagerAdapt

我的问题是我有一个ViewPager,它显示4个片段(比如:a、B、C、D)。但有时当用户单击某个东西时,我需要用另一个片段(比如E)替换它,例如A。我通过重写getItemPosition并在我的ViewPager中编写一个自定义的setCurrentItem方法来实现这一点。以下是我的课程:

MyFragmentStatePagerAdapter

public class MyFragmentStatePagerAdapter extends FragmentStatePagerAdapter {

    private Map<Integer, Fragment> overrides;

    public void setOverride(int position, Fragment fragment) {
        overrides.put(position, fragment);
    }

    ...

    @Override
    public final Fragment getItem(final int position) {
        Fragment fragment = overrides.remove(position);
        if (fragment != null) {
            return fragment;
        } else {
            ... // return corresponding base Fragment (A, B, C, D)
        }
    }

    @Override
    // this is overrideden to ensure 
    public final int getItemPosition(final Object object) {
        return PagerAdapter.POSITION_NONE;
    }

}
public class MyViewPager extends ViewPager {

    ...

    public MyAdapter adapter() {
        return (MyAdapter) this.getAdapter();
    }

    public void setCurrentItem(final int item, final Fragment fragment) {
        if (this.getAdapter() == null) {
            return;
        }

        this.adapter().setOverride(item, fragment);

        if (item == this.getCurrentItem()) {
            this.getAdapter().notifyDataSetChanged();
        } else {
            this.setCurrentItem(item);
        }
    }

}
所以这是完美的,但当我从片段中滑回并滑回时,我想再次看到一个显示,但我仍然看到E

有人能解决这个问题吗


谢谢。

很酷,我成功地让它工作了,没有性能损失。基本上,我在重写的setCurrentItem中调用notifyDataSetChanged,但仅当当前片段不是基片段时。如果有人对我的课程感兴趣:

MyPageAdapter:

public abstract class MyPageAdapter extends FragmentStatePagerAdapter {

    private final Context context;

    private final Map<Integer, Fragment> fragmentOverrides;

    private final Map<Integer, Fragment> fragmentReferences;

    private final Map<Integer, Class<? extends Fragment>> fragments;

    public MyPageAdapter(final Context context, final FragmentManager fragmentManager, final Map<Integer, Class<? extends Fragment>> fragments) {
        super(fragmentManager);
        this.context = context;
        this.fragmentOverrides = new HashMap<Integer, Fragment>();
        this.fragmentReferences = new HashMap<Integer, Fragment>();
        this.fragments = new HashMap<Integer, Class<? extends Fragment>>(fragments);
    }

    private Fragment getItemAt(final int position) {
        final Fragment overrideFragment = this.fragmentOverrides.remove(position);

        if (overrideFragment != null) {
            return overrideFragment;
        }

        return Fragment.instantiate(this.context, this.fragments.get(position).getName());
    }

    @Override
    public final Fragment getItem(final int position) {
        final Fragment fragment = this.getItemAt(position);
        this.fragmentReferences.put(position, fragment);
        return fragment;
    }

    public final Class<? extends Fragment> getInitialFragmentClass(final int position) {
        return this.fragments.get(position);
    }

    @Override
    public final int getItemPosition(final Object object) {
        return PagerAdapter.POSITION_NONE;
    }

    public final Fragment getFragment(final int position) {
        return this.fragmentReferences.get(position);
    }

    public final boolean isInitialFragment(final Class<? extends Fragment> fragmentClass) {
        return this.fragments.values().contains(fragmentClass);
    }

    public final void setOverride(final int position, final Fragment fragment) {
        this.fragmentOverrides.put(position, fragment);
    }

    @Override
    public final void destroyItem(final ViewGroup container, final int position, final Object object) {
        this.fragmentReferences.remove(position);
        super.destroyItem(container, position, object);
    }

    @Override
    public int getCount() {
        return this.fragments.size();
    }

}
public class MyViewPager extends ViewPager {

    public MyViewPager(final Context context) {
        super(context);
    }

    public MyViewPager(final Context context, final AttributeSet attrs) {
        super(context, attrs);
    }

    public final MyPageAdapter adapter() {
        if (this.getAdapter() == null) {
            return null;
        }

        if (!(this.getAdapter() instanceof MyPageAdapter)) {
            throw new IllegalStateException("Invalid adapter! The adapter must extend MyPageAdapter!");
        }

        return ((MyPageAdapter) this.getAdapter());
    }

    public final Fragment getCurrentFragment() {
        if (this.getAdapter() == null || this.getCurrentItem() < 0) {
            return null;
        }

        return this.adapter().getFragment(this.getCurrentItem());
    }

    public final void reselectCurrentItem() {
        if (this.getAdapter() != null) {
            this.getAdapter().notifyDataSetChanged();
        }
    }

    private void forceRefreshIfNeeded() {
        if (this.getAdapter() != null && 0 <= this.getCurrentItem() && this.getCurrentItem() < this.getAdapter().getCount()) {
            final Fragment currentFragment = this.adapter().getFragment(this.getCurrentItem());

            if (currentFragment != null && !currentFragment.getClass().equals(this.adapter().getInitialFragmentClass(this.getCurrentItem()))) {
                this.getAdapter().notifyDataSetChanged();
            }
        }
    }

    @Override
    public void setCurrentItem(final int item) {
        this.forceRefreshIfNeeded();
        super.setCurrentItem(item);
    }

    @Override
    public void setCurrentItem(final int item, final boolean smoothScroll) {
        this.forceRefreshIfNeeded();
        super.setCurrentItem(item, smoothScroll);
    }

    public void setCurrentItem(final int item, final Fragment fragment) {
        if (this.getAdapter() == null) {
            return;
        }

        if (!this.adapter().isInitialFragment(fragment.getClass())) {
            this.adapter().setOverride(item, fragment);
        }

        if (item == this.getCurrentItem()) {
            this.getAdapter().notifyDataSetChanged();
        } else {
            this.setCurrentItem(item);
        }
    }

}
公共抽象类MyPageAdapter扩展了FragmentStatePagerAdapter{
私人最终语境;
私有最终地图碎片覆盖;
私人最终地图碎片参考;

private final Map在getItem上粘贴一个断点,然后查看它是否再次命中。如果您从第一个片段滑开并直接返回到它,您将只看到为第三个项目调用的getItem,其中该项目正在预加载屏幕外内容。有关更多详细信息,请参见此处-尝试调用
notifyDataSetChanged()
每次在您的
setCurrentItem
上。在super.setCurrentItem起作用之前,重写setCurrentItem并调用notifyDataSetChanged,但这确实会减慢速度。也许有一种方法可以仅使被重写的片段无效。