Android ViewPager - Adding/Removing 片段无法正常工作
Android ViewPager - Adding/Removing Fragments not working properly
我有5个片段:
TimerFragment
CounterFragment
GameFragment
NoteFragment
SettingsFragment
SettingsFragment
有4个开关,控制另外4个片段的adding/removing。关闭开关会删除碎片,打开开关会添加碎片。
问题是,当我尝试删除前 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不止一次。这里有几个问题:
Also this one with the same error...
我还有一个数组,其中包含每个片段的唯一 ID,每次调用 getItemId()
时都会返回这些 ID。这也是为了避免异常。
问题是我的片段 ID 集每次都相同。关键是每次 return 一个新的唯一 ID。这是 getItemId()
的更新代码:
@Override
public long getItemId(int position) {
return View.generateViewId();
}
generateViewId()
方法每次都会生成并 return 一个新的唯一 non-clashing 视图 ID。
我有5个片段:
TimerFragment
CounterFragment
GameFragment
NoteFragment
SettingsFragment
SettingsFragment
有4个开关,控制另外4个片段的adding/removing。关闭开关会删除碎片,打开开关会添加碎片。
问题是,当我尝试删除前 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不止一次。这里有几个问题:
Also this one with the same error...
我还有一个数组,其中包含每个片段的唯一 ID,每次调用 getItemId()
时都会返回这些 ID。这也是为了避免异常。
问题是我的片段 ID 集每次都相同。关键是每次 return 一个新的唯一 ID。这是 getItemId()
的更新代码:
@Override
public long getItemId(int position) {
return View.generateViewId();
}
generateViewId()
方法每次都会生成并 return 一个新的唯一 non-clashing 视图 ID。