碎片和方向改变

Kuf*_*ffs 32 android android-fragments

使用碎片时处理方向更改的正确方法是什么?

我有一个包含2个片段的横向布局(在代码中实例化为FrameLayouts).当我切换到纵向模式(其布局仅包含仅FrameLayout保留左窗格的模式)时,不再需要右侧片段.

我收到一个错误:

E/AndroidRuntime(4519): Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f060085 for fragment myFragment{418a2200 #2 id=0x7f060085}
Run Code Online (Sandbox Code Playgroud)

假设是我的活动试图重新附加在方向更改之前的片段,但由于包含片段的视图在纵向模式下不存在,因此会引发错误.

我尝试了以下隐藏/删除/分离方法,但仍然得到错误.告诉片段不再需要它的正确方法是什么,不要尝试显示?

@Override
public void onCreate(Bundle b) {
    super.onCreate(b);
    Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragholder2);

    //rightPane is a framelayout that holds my fragment.
    if (rightPane == null && f != null) {
         FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
         ft.hide(f);     // This doesnt work
         ft.remove(f);   // neither does this
         ft.detach(f);   // or this
         ft.commit;
    }
}
Run Code Online (Sandbox Code Playgroud)

Fac*_*ony 13

我遇到了同样的问题,我想我想出了另一种解决方案.此解决方案可能更好,因为您不必将片段添加到后台堆栈.

Activity.onSaveInstanceState() 致电之前从活动中移除右侧片段super.onSaveInstanceState().这对我有用:

public MyActivity extends Activity
{   
    @Override
    public onCreate(Bundle state)
    {
        super.onCreate(state);

        // Set content view
        setContentView(R.layout.my_activity);

        // Store whether this is a dual pane layout
        mDualPane = findViewById(R.id.rightFragHolder) != null;

        // Other stuff, populate the left fragment, etc.
        .
        .
        .
        if (mDualPane)
        {
            mRightFragment = new RightFragment();
            FragmentManager fm = getFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            ft.replace(R.id.rightFragHolder, mRightFragment);
            ft.commit()
        }
    }


    @Override
    public void onSaveInstanceState(Bundle state)
    {
        if (mDualPane)
        {
            FragmentManager fm = getFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            ft.remove(mRightFragment);
            ft.commit()
        }

        super.onSaveInstanceState(state);
    }


    private boolean mDualPane;
    private Fragment mRightFragment;
}
Run Code Online (Sandbox Code Playgroud)

  • 请谨慎使用此解决方案,因为提交不会立即发生.这会导致commit和super.onSaveInstanceState(state)之间出现争用情况.有时提交在状态保存后发生,这会引发异常. (3认同)
  • @mattblang executePendingTransactions(); (2认同)

Kuf*_*ffs 0

我想我解决了。

我将片段添加到返回堆栈中,然后在活动关闭之前再次将其弹出,从而有效地摆脱了它。到目前为止似乎有效。