我有片段可以根据当前布局以两种不同的方式实例化。
使用从PageViewer
派生的适配器将这些片段加载到FragmentStatePageAdapter
中。
如果我只是在纵向或横向模式下运行应用程序,一切都很好。片段正确加载,看起来不错。
问题是当我改变方向时:片段没有改变,似乎它重用了为某个方向加载的片段,事实上如果我在下一个之后滚动寻呼机(它已经在前一个中加载了) orientation)新片段被正确加载,当我再次向后滚动时,即使是#34;起始片段"正确重新加载。
我想通过强制重新创建当前和相邻片段来解决问题,但我尝试的解决方案似乎不完整/不起作用。
我以这种方式覆盖了适配器startUpdate
方法:
public void startUpdate(ViewGroup container) {
if(isPortrait != isLastOrientationPortrait){
container.removeAllViews();
instantiateItem(container, lastPosition);
}
super.startUpdate(container);
}
这迫使从容器中消除碎片。但我不知道它是否是正确的方法以及如何将新实例化的物品放回容器中。
有什么建议吗?
答案 0 :(得分:1)
我找到了解决这个问题的方法:
而不是扩展FragmentStatePagerAdapter
类我修改了它的源代码(如果你需要它,你可以在这里找到它:https://android.googlesource.com/platform/frameworks/support/+/refs/heads/master/v4/java/android/support/v4/app/FragmentStatePagerAdapter.java)
我所做的只是以这种方式修改restoreStateMethod
:
public void restoreState(Parcelable state, ClassLoader loader) {
Log.d(TAG, "restoreState");
//We don't want to restore the fragments if the orientation changes!
if(isLastOrientationPortrait != isPortrait){
if(state != null){
Bundle bundle = (Bundle) state;
bundle.setClassLoader(loader);
Iterable<String> keys = bundle.keySet();
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
for (String key : keys) {
if (key.startsWith("f")) {
Fragment f = mFragmentManager.getFragment(bundle,
key);
mCurTransaction.remove(f);
}
}
}
isLastOrientationPortrait = isPortrait;
}else{
if (state != null) {
Bundle bundle = (Bundle)state;
bundle.setClassLoader(loader);
Parcelable[] fss = bundle.getParcelableArray("states");
mSavedState.clear();
mFragments.clear();
if (fss != null) {
for (int i=0; i<fss.length; i++) {
mSavedState.add((Fragment.SavedState)fss[i]);
}
}
Iterable<String> keys = bundle.keySet();
for (String key: keys) {
if (key.startsWith("f")) {
int index = Integer.parseInt(key.substring(1));
Fragment f = mFragmentManager.getFragment(bundle, key);
if (f != null) {
while (mFragments.size() <= index) {
mFragments.add(null);
}
f.setMenuVisibility(false);
mFragments.set(index, f);
} else {
Log.w(TAG, "Bad fragment at key " + key);
}
}
}
}
}
}
我基本上添加的是第一个if语句:
if(isLastOrientationPortrait != isPortrait){
if(state != null){
Bundle bundle = (Bundle) state;
bundle.setClassLoader(loader);
Iterable<String> keys = bundle.keySet();
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
for (String key : keys) {
if (key.startsWith("f")) {
Fragment f = mFragmentManager.getFragment(bundle,
key);
mCurTransaction.remove(f);
}
}
}
isLastOrientationPortrait = isPortrait;
}
其中isPortrait
是当前方向的布尔值,isLastOrientationPortrait
是通过onSaveInstanceState
保存的上一个方向
此力可以丢弃所有已保存的片段,并在方向更改时重新创建它们。