Android编程——自定义View类onSaveInstanceState与onRestoreInstanceState使用方法

本文介绍了在Android编程中,如何在自定义View类中使用onSaveInstanceState和onRestoreInstanceState方法来处理设备旋转时的数据保存。通过创建一个RectDrawingView示例,展示了如何在XML布局文件中声明并使用这个自定义组件,以及如何在构造方法中处理不同情况。重点讲解了这两个方法的使用,强调了数据传递的不同以及在保存和恢复过程中防止应用崩溃的关键步骤。

      在很多时候我们为获得在视图中自由绘制的能力, 需要创建一个继承于View类的定制类,然后重写onTouchEvent方法处理触摸时间,重写onDraw绘制自定义视觉效果。但这里可能会被一个问题困扰,那就是设备旋转导致数据丢失的问题,好在View类为我们提供了onSaveInstanceState和onRestoreInstanceState两个方法,虽然这两个方法和Activity两个方法很相似,但是千万别认为是一样的,因为他们的使用方法完全不同。

为了侧重数据保存的重点,我们这里简化了绘制的内容。下面定制的View子类功能是根据触摸事件发生的始末位置,绘制一组矩形。详细观察以下rectDrawingView定制类源码:

package com.art.zok.rectdrawingview;

import java.util.ArrayList;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.MotionEvent;
imp
Android 开发中,自定义 View 中的 `onSaveInstanceState()` 和 `onRestoreInstanceState()` 用于在 **Activity 或 View 被销毁并重新创建时保存和恢复状态**,比如屏幕旋转、语言切换、系统资源回收等情况。 --- ### ✅ `onSaveInstanceState()` **作用**:在 View 被销毁之前调用,用于保存当前的状态信息。 **返回值**:一个 `Parcelable` 对象,用于保存状态。 **示例代码:** ```kotlin override fun onSaveInstanceState(): Parcelable? { val superState = super.onSaveInstanceState() val savedState = MySavedState(superState) savedState.currentText = currentText savedState.fullText = fullText savedState.cursorPosition = cursorPosition return savedState } ``` --- ### ✅ `onRestoreInstanceState(Parcelable state)` **作用**:在 View 被重建时调用,用于恢复之前保存的状态。 **参数**:之前保存的 `Parcelable` 状态对象。 **示例代码:** ```kotlin override fun onRestoreInstanceState(state: Parcelable?) { if (state is MySavedState) { super.onRestoreInstanceState(state.superState) currentText = state.currentText fullText = state.fullText cursorPosition = state.cursorPosition text = currentText // 如果之前正在打字,恢复动画 if (isTyping && currentText.length < fullText.length) { setTextWithAnimation(fullText) } } else { super.onRestoreInstanceState(state) } } ``` --- ### ✅ 自定义状态保存(继承 `BaseSavedState`) 你需要定义一个静态内部继承 `BaseSavedState` 并实现 `Parcelable` 接口。 ```kotlin private class MySavedState : BaseSavedState { var currentText: String = "" var fullText: String = "" var cursorPosition: Int = 0 constructor(superState: Parcelable?) : super(superState) constructor(parcel: Parcel) : super(parcel) { currentText = parcel.readString() ?: "" fullText = parcel.readString() ?: "" cursorPosition = parcel.readInt() } override fun writeToParcel(out: Parcel, flags: Int) { super.writeToParcel(out, flags) out.writeString(currentText) out.writeString(fullText) out.writeInt(cursorPosition) } companion object { @JvmField val CREATOR = object : Parcelable.Creator<MySavedState> { override fun createFromParcel(source: Parcel) = MySavedState(source) override fun newArray(size: Int) = arrayOfNulls<MySavedState>(size) } } } ``` --- ### ✅ 使用场景 - 保存 TextView 的输入内容、光标位置 - 保存自定义 View 的状态(如颜色、进度、动画状态等) - 恢复 Activity/Fragment 中的复杂视图状态 --- ### ✅ 注意事项 1. **必须调用 `super` 方法**,以保留父状态。 2. **使用 `BaseSavedState` 是推荐做法**,而不是直接实现 `Parcelable`。 3. **避免保存大量数据**,如 Bitmap、Context 等,容易引发内存问题。 4. **状态恢复时机**:`onRestoreInstanceState()` 会在 `onFinishInflate()` 和 `onSizeChanged()` 之后调用。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值