正确保存Android视图状态(上)

正确保存Android视图状态(上)

       原文链接:http://trickyandroid.com/saving-android-view-state-correctly/

     注:以下翻译比较忠于原文
 
    今天我们将谈论Android视图状态的保存和恢复。我想让我们专注于Android视图状态,因为我发现比起保存你的Activity或Fragment的状态,这个过程只是一个小技巧。而且我觉得在整个互联网我已经看够重新发明轮子(有时真的挺难看的)。
 

    我们为什么需要保存视图状态?

       很好的问题!我有很强的信念,移动应用程序可以帮助你解决存在的问题,不增加新的。 想象一下,一个非常复杂的设置页面如下:   

       


     你将面对很多的文本域,复选框,开关,等等,你花15分钟 ~试图填补这些区域。你几乎开始准备点击闪闪的“完成”按钮,但却意外你旋转屏幕…等待它…一切都改变了。一切都回到原来的状态。(这实在让人很崩溃)
当然,有一部分用户并不在意,也将很高兴接受再次完成表单。但是老实说,自己一个正确的操作被删除了(或者更糟-疯狂的拿着火把和干草叉的用户就开始按响了你的门铃)。

让我们做正确的事情,帮助我们的用户吧!这才是应该做的!我们需要保存用户的更改直到用户明确的要求我们不需要保存。

    我要如何保存视图状态?

    下面例子有一个的简单布局,TextView和Switch:
 
     


    超级简单的布局,你可以看到。

    但是现在当我切换更改屏幕方向-然后我切换回了原来的状态:(

    Android通常自动保存类似的视图状态。但为什么在我们的例子中它没有工作?

    让我们退后一步,试图找出如何Android管理视图状态。正常的save/restore过程如下:

 

     


 
保存状态时:
1. saveHierarchyState(SparseArray<Parcelable> container) - Android framework在需要保存视图状态时调用,通常调用   dispatchSaveInstanceState().
2. dispatchSaveInstanceState(SparseArray<Parcelable> container) – 被saveHierarchyState()调用。内部调用       onSaveInstanceState()方法,并返回一个Parcelable类型表示当前View的状态。
3. Parcelable onSaveInstanceState() – 被dispatchSaveInstanceState()调用。在实现时需要覆盖此方法,已返回view的实际状态。
恢复状态时:
1. restoreHierarchyState(SparseArray<Parcelable> container) - Android framework在需要恢复视图状态时调用,这里包含一个包含之前保存的状态的SparseArray作为输入参数。
2. dispatchRestoreInstanceState(SparseArray<Parcelable> container) – 被restoreHierarchyState()调用,但是一个ViewGroup时,基于View ID遍历数组中的每个Parcelable元素,并传给到onRestoreInstanceState()作为输入参数,以恢复每个子view状态。
3. onRestoreInstanceState(Parcelable state) – 被dispatchRestoreInstanceState()调用。
 

    理解这个过程很重要的一块是,容器是整个视图层次的共享。我们将看到一块为什么这么重要。

    现在我们知道,因为视图的状态保存基于View的ID——如果没有ID的View将不被保存到容器。如果一个View没有ID-我们将无法恢复状态,因为我们不知道这个状态属于那个View。

    看起来这就是为什么之前我们切换屏幕方向时状态不保存!让我们试着给Switch添加ID(和其他所有的view):

    



    当我们再次旋转屏幕时,这正式我们想要的!这是可行的!在更改屏幕方向时,我们的view的状态得到了保存。这时我们的SparseArray看起来像:


    


    正如你可以看到,每个有ID的View的状态被存储到了SparseArray容器。

    你问这是怎么发生的-事实上我们并没有为View的状态提供任何Parcelable,答案是Android系统在做这些。Android系统知道如何保存它的内置控件的状态。

    除了ID之外,你应该明确告诉Android系统你的View需要保存其状态。

    这种做法可以简单的称作setSaveEnabled(true)。你通常不需要为内置插件做这个,但是如果你开发了自定义视图,你就需要手动enable了。

 

    未完,待续 --
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值