Fragments and Orientation change
What is the correct way to handle an orientation change when using Fragments?
I have a landscape layout that contains 2 fragments (instantiated in code into FrameLayout
s). When I switch to portrait mode (the layout of which contains only one FrameLayout
that holds the left pane only), the right hand fragment is no longer required.
I am receiving an error:
E/AndroidRuntime(4519): Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f060085 for fragment myFragment{418a2200 #2 id=0x7f060085}
which is assume is my activity trying to re-attach the fragment where it was before the orientation change but as the view that contains the fragment does not exist in portrait mode the error is thrown.
I have tried the following hide/remove/detach methods but still get the error. What is the correct way to tell a fragment it is not needed any more and do not try to display?
@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;
}
}
I ran into the same problem and I think I figured out another solution. This solution may be better because you don't have to add the fragment to the back stack.
Remove the right hand side fragment from your activity in Activity.onSaveInstanceState()
before calling super.onSaveInstanceState()
. This works for me:
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;
}
If you are retaining the fragment, try not retaining it.
setRetainInstance(false)
instead of
setRetainInstance(true)
Usually you'll have two fragments (left/right), one main activity and one container activity for the right fragment (only when shown on phone devices). This is described in this blog entry: The Android 3.0 Fragments API
public class MyActivity extends FragmentActivity
implements MyListFragment.MyContextItemSelectedListener {
@Override
public void onCreate(final Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity);
}
// Callback from ListFragment
@Override
public void myContextItemSelected(final int action, final long id) {
if (action == R.id.men_show) {
processShow(id);
}
}
private void processShow(final long id) {
if (Tools.isXlargeLand(getApplicationContext())) {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.right);
if (fragment == null ||
fragment instanceof MyEditFragment ||
(fragment instanceof MyShowFragment && ((MyShowFragment) fragment).getCurrentId() != id)) {
fragment = new MyShowFragment(id);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.right, fragment);
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.commit();
}
} else {
Intent intent = new Intent();
intent.setClass(this, MyShowActivity.class);
intent.putExtra("ID", id);
startActivityForResult(intent, MyConstants.DLG_TABLE1SHOW);
}
}
private static boolean isXlargeLand(final Context context) {
Configuration configuration = context.getResources().getConfiguration();
return (((configuration.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE) &&
configuration.orientation == Configuration.ORIENTATION_LANDSCAPE);
}
}
链接地址: http://www.djcxy.com/p/88722.html
上一篇: Selenium WebDriver:使用XPath单击SVG中的元素
下一篇: 碎片和方向改变