在方向改变Android的碎片生命周期 [英] Android Fragment lifecycle over orientation changes

查看:95
本文介绍了在方向改变Android的碎片生命周期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用兼容包使用片段目标2.2。

重新编码的活动使用的片段在一个应用程序我无法得到的取向变化/状态管理工作,所以我创建了一个小的测试应用程序,用一个FragmentActivity和一个片段。之后

从方向改变日志是怪异,多次调用该片段OnCreateView。

我显然失去了一些东西 - 就像detatching的片段重新连接它,而不是创建一个新的实例,但我看不到任何文件,这将表明我要去哪里错了。

任何人都可以阐明我在做什么错在这里请一些轻。 谢谢

日志是方向改变后如下:

 初始创建
11月12号至四日:57:15.808:D / FragmentTest.FragmentTestActivity(3143):的onCreate
11月12号至四日:57:15.945:D / FragmentTest.FragmentOne(3143):OnCreateView
11月12号至四日:57:16.081:D / FragmentTest.FragmentOne(3143):OnCreateView-> SavedInstanceState空


方向变化1
11月12号至四日:57:39.031:D / FragmentTest.FragmentOne(3143):的onSaveInstanceState
11月12号至四日:57:39.031:D / FragmentTest.FragmentTestActivity(3143):的onCreate
11月12号至四日:57:39.031:D / FragmentTest.FragmentOne(3143):OnCreateView
11月12号至四日:57:39.031:D / FragmentTest.FragmentOne(3143):OnCreateView-> SavedInstanceState不为空
11月12号至四日:57:39.031:D / FragmentTest.FragmentOne(3143):OnCreateView
11月12号至四日:57:39.167:D / FragmentTest.FragmentOne(3143):OnCreateView-> SavedInstanceState空


方向变化2
11月12号至四日:58:32.162:D / FragmentTest.FragmentOne(3143):的onSaveInstanceState
11月12号至四日:58:32.162:D / FragmentTest.FragmentOne(3143):的onSaveInstanceState
11月12号至四日:58:32.361:D / FragmentTest.FragmentTestActivity(3143):的onCreate
11月12号至四日:58:32.361:D / FragmentTest.FragmentOne(3143):OnCreateView
11月12号至四日:58:32.361:D / FragmentTest.FragmentOne(3143):OnCreateView-> SavedInstanceState不为空
11月12号至四日:58:32.361:D / FragmentTest.FragmentOne(3143):OnCreateView
11月12号至四日:58:32.361:D / FragmentTest.FragmentOne(3143):OnCreateView-> SavedInstanceState不为空
11月12号至四日:58:32.498:D / FragmentTest.FragmentOne(3143):OnCreateView
11月12号至四日:58:32.498:D / FragmentTest.FragmentOne(3143):OnCreateView-> SavedInstanceState空
 

主要活动(FragmentActivity)

 公共类FragmentTestActivity扩展FragmentActivity {
/ **第一次创建活动时调用。 * /

私有静态最后字符串变量=FragmentTest.FragmentTestActivity;


FragmentManager mFragmentManager;

@覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.main);

    Log.d(TAG的onCreate);

    mFragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();

    FragmentOne片段=新FragmentOne();

    fragmentTransaction.add(R.id.fragment_container,片段);
    fragmentTransaction.commit();
}
 

和片段

 公共类FragmentOne扩展片段{

私有静态最后字符串变量=FragmentTest.FragmentOne;

的EditText mEditText;

@覆盖
公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,
        捆绑savedInstanceState){

    Log.d(TAG,OnCreateView);

    视图V = inflater.inflate(R.layout.fragmentonelayout,集装箱,假);

    //检索的文本编辑器,并在需要时恢复上次保存的状态。
    mEditText =(EditText上)v.findViewById(R.id.editText1);

    如果(savedInstanceState!= NULL){

        Log.d(TAG,OnCreateView-> SavedInstanceState不为空);

        mEditText.setText(savedInstanceState.getCharSequence(文本));
    }
    其他 {
        Log.d(TAG,OnCreateView-> SavedInstanceState空);
    }
    返回伏;
}

@覆盖
公共无效的onSaveInstanceState(包outState){
    super.onSaveInstanceState(outState);

    Log.d(TAG,FragmentOne.onSaveInstanceState);

    //切记目前的案文,以恢复如果我们稍后再重新启动。
    outState.putCharSequence(文本,mEditText.getText());
}
 

清单

 <使用-SDK安卓的minSdkVersion =8/>

<应用
    机器人:图标=@可绘制/ ic_launcher
    机器人:标签=@字符串/ APP_NAME>
    <活动
        机器人:标签=@字符串/ APP_NAME
        机器人:名称=。activities.FragmentTestActivity
        机器人:configChanges =方向>
        <意向滤光器>
            <作用机器人:名称=android.intent.action.MAIN/>

            <类机器人:名称=android.intent.category.LAUNCHER/>
        &所述; /意图滤光器>
    < /活性GT;
< /用途>
 

解决方案

您正在分层在另一个上面的片段之一。

在配置发生变化的旧片段不被破坏 - 它增加了自己回活动时,它的重建。这是一个巨大的痛苦,在后方的大部分时间。

您可以通过使用相同的片段,而不是再造一个新出现的停止错误。只需添加这code:

 如果(savedInstanceState == NULL)
{
    mFragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();

    FragmentOne片段=新FragmentOne();

    fragmentTransaction.add(R.id.fragment_container,片段);
    fragmentTransaction.commit();
}
 

虽然被警告:如果您尝试从片段内的访问活动视图的生命周期会微妙地改变就会出现问题。 (获取从父次活动从一个片段是不容易的)。

Using the compatibility package to target 2.2 using Fragments.

After recoding an activity to use fragments in an app I could not get the orientation changes/state management working so I've created a small test app with a single FragmentActivity and a single Fragment.

The logs from the orientation changes are weird, with multiple calls to the fragments OnCreateView.

I'm obviously missing something - like detatching the fragment and reattaching it rather than creating a new instance, but I can't see any documentation which would indicate where I'm going wrong.

Can anyone shed some light on what I'm doing wrong here please. Thanks

The log is as follows after orientation changes.

Initial creation
12-04 11:57:15.808: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:57:15.945: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:16.081: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null


Orientation Change 1
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:57:39.031: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:57:39.031: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:57:39.167: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null


Orientation Change 2
12-04 11:58:32.162: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:58:32.162: D/FragmentTest.FragmentOne(3143): onSaveInstanceState
12-04 11:58:32.361: D/FragmentTest.FragmentTestActivity(3143): onCreate
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.361: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState not null
12-04 11:58:32.498: D/FragmentTest.FragmentOne(3143): OnCreateView
12-04 11:58:32.498: D/FragmentTest.FragmentOne(3143): OnCreateView->SavedInstanceState null

Main Activity (FragmentActivity)

public class FragmentTestActivity extends FragmentActivity {
/** Called when the activity is first created. */

private static final String TAG = "FragmentTest.FragmentTestActivity";


FragmentManager mFragmentManager;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Log.d(TAG, "onCreate");

    mFragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();

    FragmentOne fragment = new FragmentOne();

    fragmentTransaction.add(R.id.fragment_container, fragment);
    fragmentTransaction.commit();
}

And the fragment

public class FragmentOne extends Fragment {

private static final String TAG = "FragmentTest.FragmentOne";

EditText mEditText;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    Log.d(TAG, "OnCreateView");

    View v = inflater.inflate(R.layout.fragmentonelayout, container, false);

    // Retrieve the text editor, and restore the last saved state if needed.
    mEditText = (EditText)v.findViewById(R.id.editText1);

    if (savedInstanceState != null) {

        Log.d(TAG, "OnCreateView->SavedInstanceState not null");

        mEditText.setText(savedInstanceState.getCharSequence("text"));
    }
    else {
        Log.d(TAG,"OnCreateView->SavedInstanceState null");
    }
    return v;
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    Log.d(TAG, "FragmentOne.onSaveInstanceState");

    // Remember the current text, to restore if we later restart.
    outState.putCharSequence("text", mEditText.getText());
}

Manifest

<uses-sdk android:minSdkVersion="8" />

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:label="@string/app_name"
        android:name=".activities.FragmentTestActivity" 
        android:configChanges="orientation">
        <intent-filter >
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

解决方案

You're layering your Fragments one on top of the other.

When a config change occurs the old Fragment isn't destroyed -- it adds itself back to the Activity when it's recreated. This is a massive pain in the rear most of the time.

You can stop errors occurring by using the same Fragment rather than recreating a new one. Simply add this code:

if(savedInstanceState == null) 
{
    mFragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();

    FragmentOne fragment = new FragmentOne();

    fragmentTransaction.add(R.id.fragment_container, fragment);
    fragmentTransaction.commit();
}

Be warned though: problems will occur if you try and access Activity Views from inside the Fragment as the lifecycles will subtly change. (Getting Views from a parent Activity from a Fragment isn't easy).

这篇关于在方向改变Android的碎片生命周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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