gpt4 book ai didi

android - 使用 getItemPosition(Object object) 对 FragmentStatePagerAdapter 中的页面重新排序

转载 作者:IT老高 更新时间:2023-10-28 22:21:33 44 4
gpt4 key购买 nike

我认为 FragmentStatePagerAdapter 在重写 getItemPosition(Object object) 以重新排序页面时行为不正确。

下面是一个简单的例子。在初始状态下,页面的顺序是{A, B, C}。调用 toggleState() 后,页面顺序变为 {A, C, B}。通过覆盖 getItemPosition(Object object),我们确保当前正在查看的页面(A、B 或 C)不会改变。

public static class TestPagerAdapter extends FragmentStatePagerAdapter {
private boolean mState = true;

public TestPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}

@Override
public int getCount() {
return 3;
}

private void toggleState() {
mState = !mState;
notifyDataSetChanged();
}

private String getLabel(int position) {
switch (position) {
case 0:
return "A";
case 1:
return mState ? "B" : "C";
default:
return mState ? "C" : "B";
}
}

@Override
public int getItemPosition(Object object) {
String label = ((TestFragment) object).getLabel();
if (label.equals("A")) {
return 0;
} else if (label.equals("B")) {
return mState ? 1 : 2;
} else {
return mState ? 2 : 1;
}
}

@Override
public CharSequence getPageTitle(int position) {
return getLabel(position);
}

@Override
public Fragment getItem(int position) {
return TestFragment.newInstance(getLabel(position));
}
}

我遇到了两种看似不正确的独立行为。

  1. 如果我立即调用 toggleState()(在查看页面 A 时,在滑动到任何其他页面之前),应用程序将崩溃。

    java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2
    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
    at java.util.ArrayList.set(ArrayList.java:477)
    at android.support.v4.app.FragmentStatePagerAdapter.destroyItem(FragmentStatePagerAdapter.java:136)
    at android.support.v4.view.ViewPager.populate(ViewPager.java:867)
    at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:469)
    at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:441)
    at android.support.v4.view.ViewPager.dataSetChanged(ViewPager.java:766)
    at android.support.v4.view.ViewPager$PagerObserver.onChanged(ViewPager.java:2519)
    at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
    at android.support.v4.view.PagerAdapter.notifyDataSetChanged(PagerAdapter.java:276)
    at com.ugglynoodle.test.testfragmentstatepageradapter.MainActivity$TestPagerAdapter.toggleState(MainActivity.java:55)
    ...

    查看 FragmentStatePagerAdapter 的源代码,可以通过在调用 set( ) 在第 136 行。

  2. 如果我先滑动到页面 B,然后调用 getItem(2),创建页面 C,mFragments 现在的大小为 3 (这将防止上述崩溃立即发生)。然后我滑回页面 A,页面 C 被破坏,因为它应该是(因为它是 2 页,并且我使用默认的屏幕外页面限制 1)。现在,我调用 toggleState()。页面 B 现已销毁。但是,不会重新创建页面 C!这意味着,当我现在向右滑动时,我会看到一个空白页面。

首先,很高兴知道我是否正确并且这些实际上是错误,或者我是否做错了什么。如果它们是错误,任何人都可以提出解决方法(除了自己调试和重建支持库)吗?肯定有人成功地覆盖了 getItemPosition(Object object)(除了将所有内容都设置为 POSITION_NONE)?

我正在使用支持库的当前版本 (10)。

最佳答案

查看 FragmentStatePagerAdapter 的来源,我确切地知道出了什么问题。 FragmentStatePagerAdapter 在 ArrayLists 中缓存 fragment 和保存状态:mFragmentsmSavedState。但是当 fragment 被重新排序时,没有重新排序 mFragmentsmSavedState 元素的机制。因此,适配器会向寻呼机提供错误的 fragment 。

我已提交 an issue为此,并在问题上附加了一个固定的实现(NewFragmentStatePagerAdapter.java)。在修复中,我向 FragmentStatePagerAdapter 添加了一个 getItemId() 函数。 (这反射(reflect)了 FragmentPagerAdapter 中的重新排序实现。)始终按适配器位置存储 itemId 的数组。然后,在 notifyDataSetChanged() 中,适配器检查 itemIds 数组是否已更改。如果有,则 mFragmentsmSavedState 会相应地重新排序。进一步的修改可以在 destroyItem()saveState()restoreState() 中找到。

要使用这个类,getItemPosition()getItemId() 必须与 getItem() 一致地实现。

关于android - 使用 getItemPosition(Object object) 对 FragmentStatePagerAdapter 中的页面重新排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12510404/

44 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com