【问题标题】:Android: how do I prevent class variables being cleared on orientation change [duplicate]Android:如何防止在方向更改时清除类变量[重复]
【发布时间】:2016-05-08 23:39:28
【问题描述】:

我有一个主要活动,它有两种配置,一种会显示一个锁定为纵向的片段。

当单击此片段上的按钮时,片段会替换它,但是这个新片段可以与第二个片段并排显示。

这一切都很好,但是我在第二种状态下拦截了反向导航,以便我可以用原始配置替换片段。当改变方向时,我的所有类变量都被重置,我对片段的引用丢失了。

这里是主要活动:

打包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>

横向版本只是在框架布局上有权重。

其他片段类非常简单,目前什么都不做。

失败的代码是 onKeyDown 方法。有没有办法防止类变量在方向改变时重新初始化?我查看了处理配置更改,但未加载横向布局文件。

如果有人能提供帮助将不胜感激!!!

【问题讨论】:

标签: java android user-interface fragment android-orientation


【解决方案1】:

您应该使用this link 中提到的Activity 的onSaveInstanceState()onRestoreInstanceState() 方法。

另外,您需要在要保存的 Fragments 中调用 setRetainInstance() 方法。

查看this link 了解有关setRetainInstanceState() 的更多信息。

【讨论】:

    【解决方案2】:

    实际上,只要方向发生变化,就会调用活动的 Oncreate() 方法。因此,为了防止清除变量,请覆盖 OnConfigurationChange() 方法并在清单文件中的活动中执行此操作:-

    android:configChanges="orientation"
    

    【讨论】:

      猜你喜欢
      • 2012-10-15
      • 2012-09-03
      • 2011-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多