为什么片段无法转动过程中收到一个非空savedInstanceState包,如果是通过XML创建? [英] Why Fragment unable receive a non-null savedInstanceState bundle during rotation, if it is created through 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:机器人=http://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:机器人=http://schemas.android.com/apk/res/android
的xmlns:工具=http://schemas.android.com/tools
机器人:layout_width =match_parent
机器人:layout_height =match_parent
机器人:paddingBottom会=@扪/ activity_vertical_margin
机器人:paddingLeft =@扪/ activity_horizontal_margin
机器人:paddingRight =@扪/ activity_horizontal_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-nullsavedInstanceState
duringonCreate
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
'sonCreate
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? WhyFragment
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屋!