我认为我的应用中发生的事情的例子最适合这个问题。
用户登录后,会将其带到MainActivity。这包含带有标签的ActionBar
,默认选择一个标签,用户看到....
container1 container2
CompanyName: <EditText> | |
ProjectName: <EditText> | Welcome |
<SearchButton> | |
当用户填写这些表单并点击搜索按钮时,他们会看到...
container1 container2
<ListView> | |
BasicInfo | Welcome |
Assessment | |
Signature | |
当用户点击“评估”时,他们会看到
container1 container2
<ListView> | Question#1 |
BasicInfo | Question#2 |
Assessment | Question#3 |
Signature | Question#4 |
现在,当评估fragment
膨胀时,它会执行AsyncTask
,并为来自Views
的问题创建JSON
。现在,当用户在此屏幕上时,我不希望屏幕方向更改以再次执行网络请求和AsyncTask
。所以我将setRetainInstance(true);
放在评估Fragment
中,就像这样
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_assessment, container, false);
ab = getActivity().getActionBar();
infoList = new ArrayList<HashMap<String, String>>();
allRadio = new ArrayList<RadioGroup>();
allImageButton = new ArrayList<ImageButton>();
allSpinner = new ArrayList<Spinner>();
allEdit = new ArrayList<EditText>();
allCheck = new ArrayList<CheckBox>();
new Load().execute();
setRetainInstance(true);
return view;
}
然而,当我在评估Fragment
中翻转我的屏幕时,它不仅不会保存布局,而且会将我返回到看起来像这样的父Activity
container1 container2
CompanyName: <EditText> | |
ProjectName: <EditText> | Welcome |
<SearchButton> | |
不确定我做错了什么。可能是fragment
中的XML
名称不正确,或者容器名称不正确。这里有代码。
容器XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/MainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/header_fragment_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.2"
android:background="@drawable/green_gradient"
android:orientation="vertical" >
</LinearLayout>
<LinearLayout
android:id="@+id/content_fragment_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2"
android:background="@drawable/twoglobe_line"
android:orientation="vertical"
android:scrollbars="vertical" >
</LinearLayout>
</LinearLayout>
评估片段XML
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/basic_info_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/twoglobe_line"
android:gravity="center"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/gen_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="10dp"
android:gravity="center"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="10dp"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
</ScrollView>
所以我期待来自setRetainInstance(true);
行的不切实际的结果,或者我只是做错了?任何帮助表示赞赏。
答案 0 :(得分:2)
我不知道这是否正确,但这就是我这样做的方式,对我有用。
在我的布局中,我没有片段本身,我只有容器可以容纳它们。然后,在我的应用程序开始时,我看到我的任何片段是否已经加载(它们将在平板电脑布局中),如果不是,我会查看savedState包中是否有任何内容。如果该Bundle为null,那么我知道我的应用程序刚刚第一次启动,我可以加载我的“home”片段。否则我在onSaveInstanceState()
中放了一个密钥让我知道要加载哪个片段。所以我将让FragmentManager将其中一个加载到容器中。
答案 1 :(得分:1)
对于第一个屏幕,我会使用单独的活动。 CaseyB的答案非常好,实际上我也是这样做的(现在,当你有很多方向改变,而且背板上的一些东西,你会得到强制关闭,但它不可避免)。我要做的是第一个屏幕,使它成为自己的活动,然后调用第二个FragmentActivity并使左侧的片段静态(意味着用XML定义)。那样你就不用担心了。然后,您可以专注于正确的片段。如果设置setRetainInstance,则无需担心重新创建视图。但是,如果它进入后台,那么你将失去一切。它从不调用onDestroy,只调用onDetach。而onCreate只在第一次创建片段时调用。所以,我会避免使用onCreate,并专注于使用onActivityCreated()和onAttach()来实例化值和诸如此类
更新 - 使用onCreate()方法设置setRetainInstance(true)并调用JSON和网络代码来创建视图。在这里做它很重要,所以它只被调用一次。 这应该完全适用于方向更改和在片段之间来回切换(后端堆栈可以工作,只是你不能在backstack中将它设置为retainInstance。这是我的错字)。
然后,当片段重新启动时,你想要调用的任何其他代码,使用onAttach(),因为onCreate()不会被调用,因为它从未被破坏
然后,为了再次控制你的项目,你不能使用getActivity()。findViewById(),你必须使用this.getView()。findViewById()。我不知道为什么会这样(因为你会认为它将附加到活动视图组,但它不是)。这应该是你应该打的唯一打嗝。除此之外,它应该完美无缺。
答案 2 :(得分:1)
我实际上还没有弄清楚如何正确使用这个setRetainInstance()
方法。我不得不暂时使用
android:configChanges="orientation|keyboardHidden|screenSize
在我的清单中。我从多个人那里听说,这是不鼓励的,并且错误的方式来做到这一点。所以这个主题仍然是开放的,我将接受任何正确说明我应该如何正确使用此代码的答案。