Android ViewPager - 添加/删除碎片无法正常工作

时间:2018-03-26 09:25:09

标签: android android-fragments android-viewpager fragmentpageradapter notifydatasetchanged

我有5个片段:

  • TimerFragment
  • CounterFragment
  • GameFragment
  • NoteFragment
  • SettingsFragment

SettingsFragment有4个开关,用于控制其他4个片段的添加/删除。关闭一个开关将删除片段并打开它会添加它。

问题在于,当我尝试删除前4个片段中的任何一个时,ViewPager会删除SettingsFragment。我只能在关闭并重新启动应用程序时看到更改。

同样,当我将删除的片段添加回列表时,它会添加一个新的SettingsFragment。我必须再次关闭并重启我的应用以查看正确的更改。

这很奇怪,没有任何错误可以帮助我找出导致它的原因。我想知道为什么会这样,以及如何解决它。谢谢。

这是我的代码:

在这里,我添加片段:

frags = new String[]{".TimerFragment", ".CounterFragment", ".GameFragment",
            ".NoteFragment", ".SettingsFragment"};
    final Bundle args = new Bundle();
    boolean[] showArray = new boolean[4];
    for (int i = 0; i < frags.length; i++) {
        if (frags[i].equals(".SettingsFragment")) {
            args.putBooleanArray("showing", showArray);
            fragments.add(frags[i]);
        } else {
            boolean showing = sharedPrefs.getBoolean("Tooly" + frags[i] + ".Show",
                    true);
            showArray[i] = showing;
            if (showing) fragments.add(frags[i]);
        }
        fragIds[i] = View.generateViewId();
    }

这是我的FragmentPagerAdapter

vpTools.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {

        @Override
        public Fragment getItem(int position) {
            try {
                Fragment fragment = (Fragment) Class.forName(getPackageName() +
                        fragments.get(position)).newInstance();
                if (fragments.get(position).equals(".SettingsFragment"))
                    fragment.setArguments(args);
                return fragment;
            } catch (InstantiationException | IllegalAccessException |
                    ClassNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        public int getItemPosition(@NonNull Object object) {
            return POSITION_NONE;
        }

        @Override
        public long getItemId(int position) {
            return fragIds[position];
        }

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

以下是添加和删除片段的代码:

@SuppressLint("ApplySharedPref")
@Override
public void onSettingChanged(int pos, boolean checked) throws Exception {
    if (checked && !frags[pos].equals(fragments.get(pos))) fragments.add(pos, frags[pos]);
    else if (!checked) fragments.remove(pos);
    vpTools.getAdapter().notifyDataSetChanged();
    sharedPrefs.edit().putBoolean("Tooly" + frags[pos] + ".Show", checked).commit();
}

如果你想知道为什么我有一个字符串列表并从PagerAdapter本身实例化新的片段,那是因为我试图避免当你尝试添加片段的相同实例时发生的IllegalStateException一旦。以下是一些问题:

IllegalStateException: Can't change the tag of fragments...

Also this one with the same error...

我还为每个片段提供了一系列唯一ID,每次调用getItemId()时都会返回这些片段。这也是为了避免例外。

1 个答案:

答案 0 :(得分:0)

问题是我的片段ID每次都是一样的。关键是每次都返回一个新的唯一ID。以下是getItemId()的更新代码:

    @Override
    public long getItemId(int position) {
        return View.generateViewId();
    }

generateViewId()方法每次都会生成并返回一个新的唯一,非碰撞视图ID。