0

現在のレイアウトに従って、2 つの異なる方法でインスタンス化できるフラグメントがあります。これらのフラグメントは、PageViewerから派生したアダプタを使用してにロードされFragmentStatePageAdapterます。アプリを縦向きまたは横向きモードで実行すると、すべて問題ありません。フラグメントは正しくロードされ、正常に見えます。問題は、向きを変更したときです。フラグメントは変更されません。実際、次のページャーの後にページャーをスクロールすると、特定の向きにロードされたものを再利用するようです (以前の向きで既にロードされていました)。新しいフラグメントが正しくロードされ、もう一度スクロールすると、その「開始フラグメント」が正しくリロードされます。

現在のフラグメントと隣接するフラグメントを強制的に再作成することで問題を解決したいと考えていますが、私が試した解決策は不完全/機能していないようです。

AdapterstartUpdateメソッドを次のようにオーバーライドしました。

    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で、は現在の方向のブール値であり、isLastOrientationPortraitonSaveInstanceState

この強制により、保存されたすべてのフラグメントが破棄され、方向が変更されたときにそれらが再作成されます。

于 2012-10-19T09:16:02.590 に答える