Android:如何防止在方向更改时清除类变量 [英] Android: how do I prevent class variables being cleared on orientation change
问题描述
我有一个主要活动,它具有两种配置,一种将显示锁定为纵向的片段.
I have a main activity which has two configurations, one which will display a fragment which is locked to portrait orientation.
单击此片段上的按钮时,片段将替换它,但是可以与第二个片段并排显示此新片段.
When a button is clicked on this fragment, a fragment replaces it, however this new fragment can be displayed landscape with a second fragment side-by-side.
这一切都很好,但是我在第二种状态下拦截了向后导航,以便可以用原始配置替换这些片段.更改方向时,我所有的类变量都将重置,并且我对片段的引用也将丢失.
This all works fine, however I am intercepting back-navigation in the second state so that I can replace the fragments with the original configuration. When changing orientation all of my class variables are being reset and my references to the fragments are lost.
这是主要活动:
程序包mobileapp.group2.fragmenttest;
package mobileapp.group2.fragmenttest;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;
public class MainActivity extends FragmentActivity
implements ListPeersFragment.ListPeersFragmentListener
{
public static final String LIST_FRAGMENT_TAG = "ListPeersFragment";
public static final String GAME_FRAGMENT_TAG = "GameFragment";
public static final String OPP_FRAGMENT_TAG = "ViewOpponentFragment";
// FrameLayout references
private FrameLayout mLeftFrame;
private FrameLayout mRightFrame;
// Fragment references
private ListPeersFragment mListPeersFragment = null;
private GameFragment mGameFragment = null;
private ViewOppFragment mViewOppFragment = null;
// Boolean denoting if currently in game mode.
//private boolean mGameMode;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLeftFrame = (FrameLayout) findViewById(R.id.left_frame);
mRightFrame = (FrameLayout) findViewById(R.id.right_frame);
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
// Create fragments
if (mListPeersFragment == null)
mListPeersFragment = new ListPeersFragment();
if (mGameFragment == null)
mGameFragment = new GameFragment();
if (mViewOppFragment == null)
mViewOppFragment = new ViewOppFragment();
// In case this activity was started with special instructions from an
// Intent, pass the Intent's extras to the fragment as arguments
mListPeersFragment.setArguments(getIntent().getExtras());
// Add the fragment to the 'fragment_container' FrameLayout
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().add(R.id.left_frame, mListPeersFragment, LIST_FRAGMENT_TAG).commit();
fm.beginTransaction().add(R.id.right_frame, mViewOppFragment, OPP_FRAGMENT_TAG).commit();
//mGameMode = false;
}
// Used to intercept back navigation.
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
FragmentManager fm = getSupportFragmentManager();
if (fm.findFragmentByTag(GAME_FRAGMENT_TAG) != null)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//FragmentTransaction ft = fm.beginTransaction();
fm.beginTransaction().replace(R.id.left_frame, mListPeersFragment, LIST_FRAGMENT_TAG)
.commitAllowingStateLoss();
//mGameMode = false;
return true;
}
}
return super.onKeyDown(keyCode, event);
}
public void startGame()
{
getSupportFragmentManager().beginTransaction()
.replace(R.id.left_frame, mGameFragment, GAME_FRAGMENT_TAG).commit();
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
//mGameMode = true;
}
// Implementation of the ListPeersFragmentListener function onPeerSelected
public void onPeerSelected(int position)
{
}
}
主要活动布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/left_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/right_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
横向版本仅对框架布局具有权重.
The landscape version just has weights on the framelayouts.
其他片段类非常简单,它们目前不执行任何操作.
The other fragment classes are very simple they don't do anything at the moment.
失败的代码是onKeyDown方法.有没有一种方法可以防止在方向变化时重新初始化类变量?我已经看过处理配置更改,但随后未加载横向布局文件.
The failing code is the onKeyDown method. Is there a way to prevent the class variables from being re-initialised on orientation change? I have looked at handling config changes but then the landscape layout file is not loaded.
如果有人可以提供帮助,将不胜感激!
If anyone can help would be very appreciated!!!
推荐答案
您应使用Activity中的 onSaveInstanceState()
和 onRestoreInstanceState()
方法,如此链接.
You should use the onSaveInstanceState()
and the onRestoreInstanceState()
methods of the Activity as mentioned in this link.
此外,您还需要在要保存的片段中调用 setRetainInstance()
方法.
Also, you would need to call the setRetainInstance()
methods in the Fragments you want to save.
查看此链接,以获取有关 setRetainInstanceState()
的更多信息.
Check out this link for more information about setRetainInstanceState()
.
这篇关于Android:如何防止在方向更改时清除类变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!