0

我有片段,可以根据当前布局以两种不同的方式实例化。这些片段PageViewer使用从FragmentStatePageAdapter. 如果我以纵向或横向模式运行应用程序,一切都很好。片段已正确加载并且看起来不错。问题是当我改变方向时:片段没有改变,似乎它重用了为某个方向加载的那个,事实上如果我在下一个之后滚动寻呼机(它已经在前一个方向加载)新片段已正确加载,当我再次向后滚动时,即使“起始片段”已正确重新加载。

我想通过强制重新创建当前片段和相邻片段来解决问题,但我尝试过的解决方案似乎不完整/不起作用。

我以startUpdate这种方式覆盖了 Adapter 方法:

    public void startUpdate(ViewGroup container) {
        if(isPortrait != isLastOrientationPortrait){
            container.removeAllViews();
            instantiateItem(container, lastPosition);
        }
        super.startUpdate(container);
    }   

这迫使从容器中消除碎片。但是我不知道这是否是正确的方法以及如何将新安装的项目放回容器中。

有什么建议么?

4

1 回答 1

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

这迫使丢弃所有保存的片段并在方向更改时重新创建它们。

于 2012-10-19T09:16:02.590 回答