【Android进阶】Activity和Fragement中onSaveInstanceState()的使用详解

在activity(或者是fragement)被杀掉之前调用保存每个实例的状态,以保证该状态可以在onCreate(Bundle)或者onRestoreInstanceState(Bundle) (传入的Bundle参数是由onSaveInstanceState封装好的)中恢复。这个方法在一个activity被杀死前调用,当该activity在将来某个时刻回来时,可以恢复其先前状态。例如,如果activity B启用后位于activity A的前端,在某个时刻activity A因为系统回收资源的问题要被杀掉,A通过onSaveInstanceState将有机会保存其用户界面状态,使得将来用户返回到activity A时能通过onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢复界面的状态。


不要将这个方法和activity生命周期回调如onPause()或onStop()搞混淆了,onPause()在activtiy被放置到背景或者自行销毁时总会被调用,onStop()在activity被销毁时被调用。一个会调用onPause()和onStop(),但不触发onSaveInstanceState的例子是当用户从activity B返回到activity A时:没有必要调用B的onSaveInstanceState(Bundle),此时的B实例永远不会被恢复,因此系统会避免调用它。一个调用onPause()但不调用onSaveInstanceState的例子是当activity B启动并处在activity A的前端:如果在B的整个生命周期里A的用户界面状态都没有被破坏的话,系统是不会调用activity A的onSaveInstanceState(Bundle)的。


  默认的实现负责了大部分UI实例状态的保存,采用的方式是调用UI层上每个拥有id的view的onSaveInstanceState() ,并且保存当前获得焦点的view的id(所有保存的状态信息都会在默认的onRestoreInstanceState(Bundle)实现中恢复。如果你覆写这个方法来保存额外的没有被各个view保存的信息,你可能想要在默认实现过程中调用或者自己保存每个视图的所有状态。如果被调用,这个方法会在onStop()前被触发,但系统并不保证是否在onPause()之前或者之后触发。


以上是API文档中的解释,我们在项目中一般在onSaveInstanceState()方法中保存数据,然后再onCreate()或者是onRestoreInstanceState(Bundle)中对界面进行恢复。

一个项目中的使用情景是,在onSaveInstanceState()中记录当前的可见的第一条listview的item的position信息,然后在onRestoreInstanceState(Bundle)中对listview调用setSelection()方法对位置进行定位,这样对用户体验更加友好

代码如下:

@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		//这是用SharedPreference实现的一个类,用于对目前的数据进行存储,在调用之前,先把里面的数据清空
		stateSaver.remove(this.toString());
		// 记录可见的第一条记录
		int firstVisiblePosition = listview.getFirstVisiblePosition();
		if (mInfoAdapter.getList().size() > 0) {
			//将现在的数据存储在SharedPreference中,便于恢复
			stateSaver.put(this.toString(), mInfoAdapter.getList());
			//将位置信息保存在Bundle对象中
			outState.putInt("firstVisiblePosition", firstVisiblePosition);
		}
	}

在onViewStateRestored()方法中进行数据的恢复

@Override
	public void onViewStateRestored(Bundle savedInstanceState) {
		super.onViewStateRestored(savedInstanceState);
		//初始化显示位置
		int firstVisiblePosition = 0;
		//获得保存的位置信息
		if (savedInstanceState != null) {
			firstVisiblePosition = savedInstanceState.getInt("firstVisiblePosition");
		}
		if (stateSaver.get(this.toString()) != null) {
			List<EngineeringInfo> list = stateSaver.get(this.toString());
			if (list.size() > 0) {
				mInfoAdapter.setList(list);
				//恢复到上次看到的位置
				listview.setSelection(firstVisiblePosition);
			}
		}
	}

如有疑问,请留言



转载于:https://www.cnblogs.com/oversea201405/p/3749562.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FragmentAndroid的一种UI组件,它可以嵌入到Activity,用于实现灵活的UI设计和多屏幕适配。下面介绍一下Fragment使用: 1. 创建Fragment类 首先需要创建一个继承自Fragment的子类,并实现其onCreateView()方法,该方法返回一个View对象,该View对象就是该Fragment的界面布局。 2. 在Activity添加FragmentActivity的布局文件添加一个FrameLayout容器,然后在Activity的代码通过FragmentManager和FragmentTransaction来管理和添加Fragment。例如: ```java MyFragment fragment = new MyFragment(); FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.add(R.id.fragment_container, fragment); transaction.commit(); ``` 其,R.id.fragment_container是FrameLayout容器的id。 3. Fragment的生命周期 与Activity类似,Fragment也有自己的生命周期,包括onCreate、onAttach、onCreateView、onActivityCreated、onStart、onResume、onPause、onStop、onDestroyView、onDestroy、onDetach等方法。在Fragment的生命周期,可以通过这些方法来处理一些与UI相关的逻辑。例如,可以在onCreateView方法初始化布局,可以在onStart方法开始某个操作,可以在onPause方法停止某个操作等。 4. Fragment之间的通信 在Activity,可以通过Intent来实现不同组件之间的通信,而在Fragment,可以通过接口来实现Fragment之间的通信。具体来说,可以在一个Fragment定义一个接口,并在另一个Fragment实现该接口,从而实现两个Fragment之间的通信。例如: ```java public class MyFragment extends Fragment { public interface OnButtonClickListener { void onButtonClick(); } private OnButtonClickListener mListener; @Override public void onAttach(Context context) { super.onAttach(context); try { mListener = (OnButtonClickListener) context; } catch (ClassCastException e) { throw new ClassCastException(context.toString() + " must implement OnButtonClickListener"); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_layout, container, false); Button button = view.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mListener != null) { mListener.onButtonClick(); } } }); return view; } } public class AnotherFragment extends Fragment implements MyFragment.OnButtonClickListener { @Override public void onButtonClick() { // do something } } ``` 在上面的例子,MyFragment定义了一个OnButtonClickListener接口,并在onAttach方法将该接口的实现赋值给mListener变量。在MyFragment的界面布局,当按钮被点击时,会调用mListener的onButtonClick方法。另一个Fragment AnotherFragment实现了该接口,并在onButtonClick方法对按钮点击事件进行处理。这样,就实现了两个Fragment之间的通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值