You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带自定义属性的Android货币切换视图返回Fragment后状态重置如何解决

问题原因

  1. 当前状态保存逻辑仅处理了子View的状态存储,没有存储SwitchableTextField自身的三个自定义状态变量(defaultCurrency、conversionCurrency、conversionDirection),页面重建时这三个变量会被构造方法内的applyUserAttributes重置为XML配置的初始值。
  2. Android View重建流程为:先执行构造方法调用applyUserAttributes加载初始属性,再执行onRestoreInstanceState恢复保存的状态,只需将自定义变量加入状态保存恢复逻辑,即可用恢复的正确值覆盖初始值解决问题。

修改方案

1. 扩展SavedState类,新增自定义状态的存储逻辑

internal class SavedState : AbsSavedState {
    internal var childrenStates: SparseArray<Parcelable>? = null
    // 新增三个自定义状态字段
    internal var defaultCurrency: String? = null
    internal var conversionCurrency: String? = null
    internal var conversionDirection: Boolean = false

    constructor(superState: Parcelable?) : super(superState)

    @Suppress("UNCHECKED_CAST")
    constructor(source: Parcel) : super(source) {
        childrenStates = source.readSparseArray(javaClass.classLoader)
        // 读取保存的自定义状态
        defaultCurrency = source.readString()
        conversionCurrency = source.readString()
        conversionDirection = source.readByte() != 0.toByte()
    }

    @Suppress("UNCHECKED_CAST")
    override fun writeToParcel(out: Parcel, flags: Int) {
        super.writeToParcel(out, flags)
        out.writeSparseArray(childrenStates as SparseArray<Any>)
        // 写入自定义状态
        out.writeString(defaultCurrency)
        out.writeString(conversionCurrency)
        out.writeByte(if (conversionDirection) 1 else 0)
    }

    companion object {
        @Suppress("UNUSED")
        @JvmField
        val CREATOR = object : Parcelable.Creator<SavedState> {
            override fun createFromParcel(source: Parcel) = SavedState(source)
            override fun newArray(size: Int): Array<SavedState?> = arrayOfNulls(size)
        }
    }
}

2. 修改onSaveInstanceState,存储当前自定义状态

override fun onSaveInstanceState(): Parcelable? {
    return SavedState(super.onSaveInstanceState()).apply {
        childrenStates = saveChildViewStates()
        // 保存当前自定义状态
        defaultCurrency = this@SwitchableTextField.defaultCurrency
        conversionCurrency = this@SwitchableTextField.conversionCurrency
        conversionDirection = this@SwitchableTextField.conversionDirection
    }
}

3. 修改onRestoreInstanceState,恢复自定义状态并刷新UI

public override fun onRestoreInstanceState(state: Parcelable?) {
    when (state) {
        is SavedState -> {
            super.onRestoreInstanceState(state.superState)
            state.childrenStates?.let { restoreChildViewStates(it) }
            // 恢复自定义状态,自动覆盖构造方法设置的初始值
            state.defaultCurrency?.let { defaultCurrency = it }
            state.conversionCurrency?.let { conversionCurrency = it }
            conversionDirection = state.conversionDirection
            // 重新触发金额换算,保证显示结果正确
            convertAmount(mainAmount)
        }
        else -> super.onRestoreInstanceState(state)
    }
}

内容的提问来源于stack exchange,提问作者Maxime Michel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 16:30:00