片段setRetainInstance(true)保存View属性 [英] Fragment setRetainInstance(true) save View properties
问题描述
我对保存保存在Android片段内部的View状态的最佳做法感到困惑.
I'm confused about the best practice for saving the states of Views that live inside of fragments in Android.
我认为setRetainInstance(true)
可以解决问题;但是,尽管这确实保留了在Fragment
中声明的旧的全局View
引用,但在扩展布局时将不会使用这些视图.因此,我必须手动将属性从旧的全局View引用转移到膨胀布局中的新View.请参阅下面的代码,了解我的操作方式.
I thought that setRetainInstance(true)
would do the trick; however, while this does retain the old global View
references declared in the Fragment
, those Views will not be used when inflating the layout. Thus, I have to manually transfer the properties from the old global View references to the new Views in the inflated layout. See the code below for how I'm doing this.
public static class MyFragment extends Fragment {
// I need to save the state of two views in the fragment
ProgressBar mProgress;
TextView mText;
@Override public void onCreate(Bundle savedInstanceState) {
// savedInstanceState == null if setRetainInstance == true
super.onCreate(savedInstanceState);
// Retain the instance between configuration changes
setRetainInstance(true);
}
@Override public View onCreateView(LayoutInflater i, ViewGroup c, Bundle b) {
// Inflate xml layout for fragement (orientation dependent)
View v = i.inflate(R.layout.fragment_main, c, false);
// Grab Views from layout
ProgressBar tmpProgress = (ProgressBar) v.findViewById(R.id.progress);
TextView tmpText = (TextView) v.findViewById(R.id.text);
// If View References exist, transfer state from previous Views
if(mProgress != null){
tmpProgress.setProgress(mProgress.getProgress());
tmpText.setText(mText.getText());
}
// Replace View references
mProgress = tmpProgress;
mText = tmpText;
return v;
}
}
我觉得setRetainInstanceState(true)
应该主要用于使片段保持活动状态,以便后台进程可以与其保持连接.如果是这种情况,我是否不应该使用此方法来保留View
s的状态?
It's my feeling that setRetainInstanceState(true)
should mainly be used for keeping a fragment alive so that background processes can maintain a connection to it. If that's the case should I not be using this method to retain the states of my View
s?
更具体地说:
- 如果
setRetainInstanceState
是true
,以上代码是在定向调用之间保留View
状态的最佳方法吗? - 如果我不与后台任务交互,是否应该只使用
setRetainInstanceState(false)
并使用Bundle
来维护View状态? (注意:如果setRetainInstance == true
,不能使用捆绑包)
- if
setRetainInstanceState
istrue
, is the above code the best way to retain theView
states between orientation calls? - If I'm not interacting with background tasks, should I just use
setRetainInstanceState(false)
and useBundle
s to maintain the View states? (Note: bundles cannot be used ifsetRetainInstance == true
)
推荐答案
使用setRetainInstance
请勿将视图保留在内存中,而只将与您基于tag
或ID
的Singleton
实例相同给你的片段.很好,因为当您Fragment
进入后台时,您的视图将被破坏,而不是不必要的内存.
Use setRetainInstance
DO NOT keep your view in memory just keep same instance as a kind of Singleton
based on tag
or ID
that you give to your fragment. It's good because when you Fragment
goes to background your view is destroyed and not unecessary memory.
回答两个问题:
-
不要保留您的视图!每次调用onCreateView时都要重新创建视图.为了保持状态和更多状态,请使用全局变量.
Do not keep your view created! Recreate your view every time onCreateView is called. To keep states and more use global variables.
否,一旦您将其设置为Fragment
,Android OS将为相同的标签或ID保留相同的实例,因此当进入后台时,请记住以onSaveInstanceState
的视图状态保存您的Bundle
以便下次恢复视图状态.
No, once you set it your Fragment
, Android OS will keep same instance for same tag or ID so when it goes to background keep in mind to save your Bundle
with view state at onSaveInstanceState
to recover view status at next time.
在此处详细了解有关片段生命周期的信息: http://developer.android.com/guide/components/fragments.html#Lifecycle
Read more about Fragments lifecycle here: http://developer.android.com/guide/components/fragments.html#Lifecycle
关于onSaveInstanceState
的更多信息,请参见:
And about onSaveInstanceState
, see more here: http://developer.android.com/reference/android/app/Fragment.html#onSaveInstanceState(android.os.Bundle)
例如,您可以执行以下操作:
For example you could do something like that:
package com.example.stackoverflowsandbox;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MyFragment extends Fragment {
public static String VIEW_STATE_A = "a";
public static String VIEW_STATE_B = "b";
public static String VIEW_STATE_C = "c";
private String currentState = MyFragment.VIEW_STATE_A;
private View view;
public void changeStateTo( final String newState ) {
if ( this.currentState != newState ) {
this.currentState = newState;
this.updateViewState( this.currentState );
}
}
@Override
public View onCreateView( final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState ) {
this.setRetainInstance( true );
this.view = inflater.inflate( R.layout.my_view, null );
this.updateViewState( this.currentState );
return this.view;
}
@Override
public void onDestroyView() {
this.view = null; // release the reference to GC
super.onDestroyView();
}
private void updateViewState( final String state ) {
// do what you want to do with your view here...
}
}
通过changeStateTo
更改fragment
状态.
这篇关于片段setRetainInstance(true)保存View属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!