Android:如何防止在方向更改时清除类变量 [英] Android: how do I prevent class variables being cleared on orientation change

查看:62
本文介绍了Android:如何防止在方向更改时清除类变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆