为什么片段无法转动过程中收到一个非空savedInstanceState包,如果是通过XML创建? [英] Why Fragment unable receive a non-null savedInstanceState bundle during rotation, if it is created through XML?

查看:102
本文介绍了为什么片段无法转动过程中收到一个非空savedInstanceState包,如果是通过XML创建?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下几个非常简单的片段。

UiFragment.java

 包com.example.test;进口android.os.Bundle;
进口android.util.Log;
进口android.view.LayoutInflater;
进口android.view.View;
进口android.view.ViewGroup;进口com.actionbarsherlock.app.SherlockFragment;/ **
 *这是显示的用户界面,将工作进行更新完成片段
 *在保留片段。
 * /
公共类UiFragment扩展SherlockFragment {
    @覆盖
    公共无效onActivityCreated(捆绑savedInstanceState){
        Log.i(卓,UiFragment onActivityCreated);        super.onActivityCreated(savedInstanceState);
    }    @覆盖
    公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,
            捆绑savedInstanceState){
        Log.i(卓,UiFragment onCreateView);        视图V = inflater.inflate(R.layout.uifragment,集装箱,FALSE);        返回伏;
    }    @覆盖
    公共无效的onCreate(捆绑savedInstanceState){
        Log.i(卓,UiFragment的onCreate);        super.onCreate(savedInstanceState);        如果(savedInstanceState!= NULL){
            Log.i(卓, - > UiFragment能够得到savedInstanceState的数据:+ savedInstanceState.getInt(值));
        }
    }    @覆盖
    公共无效的onSaveInstanceState(捆绑outState){
        super.onSaveInstanceState(outState);
        outState.putInt(价值,111222);
    }
}

uifragment.xml

 <?XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:方向=垂直
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:填充=8DP>    <的TextView
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:layout_gravity =中心
        机器人:textAppearance =机器人:ATTR / textAppearanceMedium
        机器人:文字=fragment_retain_instance_msg/>< / LinearLayout中>

我意识到,如果我是它通过Java code重视FragmentActivity。

MainActivity.java

 包com.example.test;进口android.os.Bundle;
进口android.util.Log;进口com.actionbarsherlock.app.SherlockFragmentActivity;公共类MainActivity扩展SherlockFragmentActivity {    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        Log.i(卓,MainActivity的onCreate);        super.onCreate(savedInstanceState);        如果(savedInstanceState!= NULL){
            Log.i(卓, - > MainActivity能够得到savedInstanceState的数据:+ savedInstanceState.getInt(值));
        }        //?
        //setContentView(R.layout.activity_main);        如果(savedInstanceState == NULL){
            getSupportFragmentManager()调用BeginTransaction()。添加(android.R.id.content,
                新UiFragment())提交()。
        }
    }    @覆盖
    公共无效的onSaveInstanceState(捆绑outState){
        super.onSaveInstanceState(outState);
        outState.putInt(价值,888999);
    }
}

每次当我在片段能够得到非空 savedInstanceState >的onCreate

  02-26 00:36:48.777:I /卓(17740):MainActivity的onCreate
02-26 00:36:48.812:I /卓(17740):UiFragment的onCreate
02-26 00:36:49.031:I /卓(17740):UiFragment onCreateView
02-26 00:36:49.035:I /卓(17740):UiFragment onActivityCreated
[旋转这里发生]
02-26 00:37:37.472:I /卓(17740):MainActivity的onCreate
02-26 00:37:37.472:I /卓(17740):UiFragment的onCreate
02-26 00:37:37.472:I /卓(17740): - > UiFragment能够得到savedInstanceState的数据:111222
02-26 00:37:37.472:I /卓(17740): - > MainActivity能够得到savedInstanceState的数据:888999
02-26 00:37:37.511:I /卓(17740):UiFragment onCreateView
02-26 00:37:37.511:I /卓(17740):UiFragment onActivityCreated

但是,如果我更换code在 MainActivity 的onCreate

 如果(savedInstanceState == NULL){
    getSupportFragmentManager()调用BeginTransaction()。添加(android.R.id.content,
        新UiFragment())提交()。
}

通过XML片断创建

 的setContentView(R.layout.activity_main);

activity_main.xml中

 <的RelativeLayout的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    的xmlns:工具=htt​​p://schemas.android.com/tool​​s
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:paddingBottom会=@扪/ activity_vertical_margin
    机器人:paddingLeft =@扪/ activity_horizo​​ntal_margin
    机器人:paddingRight =@扪/ activity_horizo​​ntal_margin
    机器人:paddingTop =@扪/ activity_vertical_margin
    工具:上下文=MainActivity。>    <片段类=com.example.test.UiFragment
        机器人:layout_width =match_parent
        机器人:layout_height =match_parent/>< / RelativeLayout的>

我会得到以下日志,当我进行旋转。

  02-26 00:39:23.437:I /卓(18055):MainActivity的onCreate
02-26 00:39:23.734:I /卓(18055):UiFragment的onCreate
02-26 00:39:23.734:I /卓(18055):UiFragment onCreateView
02-26 00:39:23.754:I /卓(18055):UiFragment onActivityCreated
[旋转这里发生]
02-26 00:39:27.703:I /卓(18055):MainActivity的onCreate
02-26 00:39:27.703:I /卓(18055): - > MainActivity能够得到savedInstanceState的数据:888999
02-26 00:39:27.746:I /卓(18055):UiFragment的onCreate
02-26 00:39:27.746:I /卓(18055):UiFragment onCreateView
02-26 00:39:27.750:I /卓(18055):UiFragment onActivityCreated

为什么在片段等行为的区别? 为什么片段收不到旋转过程中一个非空savedInstanceState束,如果是通过XML创建?


解决方案

  

被实例化的片段必须有某种独特的
  标识符,以便它可以与previous例如,如果重新关联
  父活动需要被破坏并重新创建。这可以是
  提供这些方式:


供应ID,以片段XML标签解决问题。

 <片段类=com.example.test.UiFragment
    机器人:ID =@ + ID / myFragment
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent/>

I have the following very simple Fragment.

UiFragment.java

package com.example.test;

import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.actionbarsherlock.app.SherlockFragment;

/**
 * This is a fragment showing UI that will be updated from work done
 * in the retained fragment.
 */
public class UiFragment extends SherlockFragment {


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        Log.i("CHEOK", "UiFragment onActivityCreated");

        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        Log.i("CHEOK", "UiFragment onCreateView");

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

        return v;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.i("CHEOK", "UiFragment onCreate");

        super.onCreate(savedInstanceState);

        if (savedInstanceState != null) {
            Log.i("CHEOK", "--> UiFragment able get savedInstanceState's data : " + savedInstanceState.getInt("value"));
        }       
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("value", 111222);        
    }    
}

uifragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="8dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="fragment_retain_instance_msg" />

</LinearLayout>

I realize if I were attach it to FragmentActivity through Java code.

MainActivity.java

package com.example.test;

import android.os.Bundle;
import android.util.Log;

import com.actionbarsherlock.app.SherlockFragmentActivity;

public class MainActivity extends SherlockFragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.i("CHEOK", "MainActivity onCreate");

        super.onCreate(savedInstanceState);

        if (savedInstanceState != null) {
            Log.i("CHEOK", "--> MainActivity able get savedInstanceState's data : " + savedInstanceState.getInt("value"));
        }

        // ???
        //setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction().add(android.R.id.content,
                new UiFragment()).commit();
        }       
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("value", 888999);        
    }   
}

Everytime when I perform rotation, my Fragment able to get non-null savedInstanceState during onCreate

02-26 00:36:48.777: I/CHEOK(17740): MainActivity onCreate
02-26 00:36:48.812: I/CHEOK(17740): UiFragment onCreate
02-26 00:36:49.031: I/CHEOK(17740): UiFragment onCreateView
02-26 00:36:49.035: I/CHEOK(17740): UiFragment onActivityCreated
[Rotation happens here]
02-26 00:37:37.472: I/CHEOK(17740): MainActivity onCreate
02-26 00:37:37.472: I/CHEOK(17740): UiFragment onCreate
02-26 00:37:37.472: I/CHEOK(17740): --> UiFragment able get savedInstanceState's data : 111222
02-26 00:37:37.472: I/CHEOK(17740): --> MainActivity able get savedInstanceState's data : 888999
02-26 00:37:37.511: I/CHEOK(17740): UiFragment onCreateView
02-26 00:37:37.511: I/CHEOK(17740): UiFragment onActivityCreated

However, if I were replace the code in MainActivity's onCreate

if (savedInstanceState == null) {
    getSupportFragmentManager().beginTransaction().add(android.R.id.content,
        new UiFragment()).commit();
}

with fragment creation through XML

setContentView(R.layout.activity_main);

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <fragment class="com.example.test.UiFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

I will get the following log when I perform rotation.

02-26 00:39:23.437: I/CHEOK(18055): MainActivity onCreate
02-26 00:39:23.734: I/CHEOK(18055): UiFragment onCreate
02-26 00:39:23.734: I/CHEOK(18055): UiFragment onCreateView
02-26 00:39:23.754: I/CHEOK(18055): UiFragment onActivityCreated
[Rotation happens here]
02-26 00:39:27.703: I/CHEOK(18055): MainActivity onCreate
02-26 00:39:27.703: I/CHEOK(18055): --> MainActivity able get savedInstanceState's data : 888999
02-26 00:39:27.746: I/CHEOK(18055): UiFragment onCreate
02-26 00:39:27.746: I/CHEOK(18055): UiFragment onCreateView
02-26 00:39:27.750: I/CHEOK(18055): UiFragment onActivityCreated

Why there is such difference in Fragment behavior? Why Fragment unable receive a non-null savedInstanceState bundle during rotation, if it is created through XML?

解决方案

The fragment being instantiated must have some kind of unique identifier so that it can be re-associated with a previous instance if the parent activity needs to be destroyed and recreated. This can be provided these ways:

Supplying id to fragment XML tag solve the problem.

<fragment class="com.example.test.UiFragment"
    android:id="@+id/myFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

这篇关于为什么片段无法转动过程中收到一个非空savedInstanceState包,如果是通过XML创建?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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