У меня есть основное действие, которое имеет две конфигурации, в которых будет отображаться фрагмент, который заблокирован для портретной ориентации.Android: как предотвратить очистку переменных класса при изменении ориентации?
При нажатии на этот фрагмент фрагмент заменяет его, однако этот новый фрагмент может отображаться в виде пейзажа со вторым фрагментом бок о бок.
Это все работает нормально, однако я перехватываю обратную навигацию во втором состоянии, чтобы заменить фрагменты исходной конфигурацией. При изменении ориентации все мои переменные класса сбрасываются и мои ссылки на фрагменты теряются.
Вот основной вид деятельности:
пакет 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>
Пейзаж версия только имеет весов на framelayouts.
Другие классы фрагментов очень просты, они ничего не делают в данный момент.
Неудачный код - метод onKeyDown. Есть ли способ предотвратить повторную инициализацию переменных класса при изменении ориентации? Я рассмотрел обработку изменений конфигурации, но затем файл ландшафтного макета не загружен.
Если кто-то может помочь, очень признателен!
Вы можете 'setRetainInstance (true)', чтобы остановить повторное создание фрагмента при изменении ориентации. http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean) –
начал работу с дизайном MVC – Pomagranite