Android 在配置更改上保存和恢复片段视图状态
编辑 我一直在搜索和阅读很多关于这个话题的文章,但我就是找不到解决问题的方法。我不知道我是做错了什么,还是设计错了什么 我的活动中有一个片段,这个片段有三种不同的布局,出现或消失(这取决于用户做了什么或正在做什么)。此外,还将创建一个视图组,动态添加新的文本视图。当屏幕的方向改变时,我想保留片段的所有视图,保持布局不可见,保持所有文本视图不变,等等 我知道当屏幕方向改变时,片段和活动的生命周期是如何工作的,但我不知道如何管理它。如何以及从何处恢复仍在内存中的片段,如何恢复视图并在onCreateView中返回它。我对这件事感到困惑 下面是片段的xml文档Android 在配置更改上保存和恢复片段视图状态,android,android-fragments,fragment,Android,Android Fragments,Fragment,编辑 我一直在搜索和阅读很多关于这个话题的文章,但我就是找不到解决问题的方法。我不知道我是做错了什么,还是设计错了什么 我的活动中有一个片段,这个片段有三种不同的布局,出现或消失(这取决于用户做了什么或正在做什么)。此外,还将创建一个视图组,动态添加新的文本视图。当屏幕的方向改变时,我想保留片段的所有视图,保持布局不可见,保持所有文本视图不变,等等 我知道当屏幕方向改变时,片段和活动的生命周期是如何工作的,但我不知道如何管理它。如何以及从何处恢复仍在内存中的片段,如何恢复视图并在onCreate
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true"
android:weightSum="1">
<RelativeLayout
android:id="@+id/top_layout"
android:layout_width="match_parent"
android:layout_height="40dp"
android:padding="8dp"
android:animateLayoutChanges="true"
android:weightSum="1"
android:background="#fc033967">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:fontFamily="sans-serif-condensed"
android:textColor="#ffffff"
android:text="@string/scan_new_code_location"
android:layout_marginLeft="5dp"
android:layout_marginRight="20dp"
android:layout_gravity="center_vertical"
android:id="@+id/location_textView" />
<LinearLayout
android:id="@+id/new_location_layout"
android:layout_width="wrap_content"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton
android:id="@+id/new_location_image"
android:layout_width="18dp"
android:layout_height="18dp"
android:background="@android:color/transparent"
android:layout_marginLeft="20dp"
android:src="@drawable/ic_action_new"
android:layout_gravity="center_vertical"/>
<Button
android:id="@+id/boton_nuevaLoc"
android:text="@string/newLocation"
android:fontFamily="sans-serif-condensed"
android:textColor="#ffffff"
android:textSize="15sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="20dp"
android:background="@android:color/transparent"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
<RelativeLayout
android:id="@+id/cancel_ingress_layout"
android:layout_gravity="center_vertical"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true">
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/location_container"
android:layout_width="match_parent"
android:layout_height="40dp"
android:padding="8dp"
android:layout_gravity="center"
android:animateLayoutChanges="true"
android:weightSum="1"
android:background="#fc033967">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="horizontal">
<ImageButton
android:id="@+id/location_image"
android:layout_width="18dp"
android:layout_height="18dp"
android:background="@android:color/transparent"
android:layout_marginLeft="20dp"
android:src="@android:drawable/ic_menu_mylocation"
android:layout_gravity="center_vertical"/>
<TextView
android:id="@+id/added_location_textView"
android:text="@string/newLocation"
android:fontFamily="sans-serif-condensed"
android:textColor="#ffffff"
android:textSize="15sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="20dp"
android:background="@android:color/transparent"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
<RelativeLayout
android:id="@+id/close_location_container"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true">
<ImageButton
android:id="@+id/close_location_image"
android:layout_width="18dp"
android:layout_height="18dp"
android:background="@android:color/transparent"
android:layout_marginLeft="20dp"
android:src="@android:drawable/ic_menu_send"
android:layout_gravity="center_vertical"/>
</RelativeLayout>
</RelativeLayout>
<LinearLayout android:id="@+id/container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@android:color/transparent"
android:layout_marginTop="15dp"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:animateLayoutChanges="true"
android:visibility="invisible"/>
<EditText
android:id="@+id/scan_reader_EditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="500dp"
android:inputType="text"/>
</LinearLayout>
***************编辑***********************
嗯。多亏了Endzeit,我才解决了这个问题
我需要这样做:
在片段中,我创建了一个视图变量,将视图引用到片段并保留实例。
然后,如果存在已保存的实例,我将在onCreateView中返回对已保存视图的引用。这样地:
公共类LocationFragment扩展了片段{
private static final String TAG = "LocationFragment";
//Graphics elements
@Bind(R.id.top_layout) RelativeLayout topLayout;
.
.
.
static ViewGroup panelIngresarItem;
**View rootView**;
public LocationFragment() {
// Required empty public constructor
}
public static LocationFragment newInstance() {
LocationFragment fragment = new LocationFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
**setRetainInstance(true)**;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
**if (savedInstanceState == null)** {
**rootView = inflater.inflate(R.layout.fragment_location, container, false);**
ButterKnife.bind(this, rootView);
}
**return rootView;**
}
public void onViewCreated(View view, Bundle savedInstanceState){
if(savedInstanceState == null) {
locationTextView.setVisibility(View.GONE);
translation = topLayout.getMeasuredWidth() - addLocationLayout.getMeasuredWidth() +
newLocationButton.getMeasuredWidth();
cancelScanLayout.setOnClickListener(new CloseButtonListener());
cancelScanLayout.setClickable(false);
// Add item listener, for only create one listener
addItemListener = new AddItemListener();
closeImageButton.setOnClickListener(new CloseLocationListener());
panelIngresarItem = (ViewGroup) LayoutInflater.from(this.getActivity()).inflate(
R.layout.new_item_panel, containerLayout, false);
panelIngresarItem.setOnClickListener(addItemListener);
scanLocationMode = true;
closeLayout.setVisibility(View.GONE);
super.onViewCreated(view, savedInstanceState);
}
}
.
.
.
}
然后在活动中,将片段放入FragmentManager中,如果有保存的实例,则再次获取该片段
public class MainActivity extends AppCompatActivity {
private FragmentManager fm;
public static final String FRAG_LOCATION = "frag_loc";
private LocationFragment fragmentLocation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fm = getSupportFragmentManager();
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
fragmentLocation = new LocationFragment();
} else {
fragmentLocation = (LocationFragment) fm
.getFragment(savedInstanceState,FRAG_LOCATION);
}
fm.beginTransaction()
.replace(R.id.container_fragment, fragmentLocation)
.commit();
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setIcon(R.drawable.ic_launcher_other);
}
@Override
public void onSaveInstanceState(Bundle outState) {
if(fragmentLocation != null) {
getSupportFragmentManager().putFragment(outState,FRAG_LOCATION, fragmentLocation);
}
super.onSaveInstanceState(outState);
}
.
.
.
}
例如,我想保存片段和活动的旋转状态 您必须在activities
onSaveInstanceState()
方法上保存片段
要实现这一点,请将代码更改为:
public static final String TAG_FRAG_LOCATION = "key_frag_loc";
private LocationFragment fragmentLocation;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
fm = getSupportFragmentManager();
if(savedInstanceState != null) {
fragmentLocation = (LocationFragment) fragmentManager
.findFragmentByTag(savedInstanceState.getString(TAG_FRAG_LOCATION));
} else {
fragmentLocation = new LocationFragment();
}
fm.beginTransaction()
.replace(R.id.container_fragment, fragmentLocation)
.commit();
...
}
@Override
public void onSaveInstanceState(Bundle outState) {
if(fragmentLocation != null) {
outState.putString(TAG_FRAG_EXAMS, fragmentLocation.getTag());
}
super.onSaveInstanceState(outState);
}
public class MainActivity extends AppCompatActivity {
private FragmentManager fm;
public static final String FRAG_LOCATION = "frag_loc";
private LocationFragment fragmentLocation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fm = getSupportFragmentManager();
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
fragmentLocation = new LocationFragment();
} else {
fragmentLocation = (LocationFragment) fm
.getFragment(savedInstanceState,FRAG_LOCATION);
}
fm.beginTransaction()
.replace(R.id.container_fragment, fragmentLocation)
.commit();
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setIcon(R.drawable.ic_launcher_other);
}
@Override
public void onSaveInstanceState(Bundle outState) {
if(fragmentLocation != null) {
getSupportFragmentManager().putFragment(outState,FRAG_LOCATION, fragmentLocation);
}
super.onSaveInstanceState(outState);
}
.
.
.
}
public static final String TAG_FRAG_LOCATION = "key_frag_loc";
private LocationFragment fragmentLocation;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
fm = getSupportFragmentManager();
if(savedInstanceState != null) {
fragmentLocation = (LocationFragment) fragmentManager
.findFragmentByTag(savedInstanceState.getString(TAG_FRAG_LOCATION));
} else {
fragmentLocation = new LocationFragment();
}
fm.beginTransaction()
.replace(R.id.container_fragment, fragmentLocation)
.commit();
...
}
@Override
public void onSaveInstanceState(Bundle outState) {
if(fragmentLocation != null) {
outState.putString(TAG_FRAG_EXAMS, fragmentLocation.getTag());
}
super.onSaveInstanceState(outState);
}