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

如何在onSaveInstanceState中存储Drawable到Bundle?

如何在Bundle中存储Drawable?

Bundle本身没有直接存储Drawable的方法,你可以通过以下几种方式实现:

方案1:转成Bitmap存储(通用方案)

Bitmap实现了Parcelable接口,能直接用putParcelable存入Bundle。如果你的Drawable是BitmapDrawable,直接提取Bitmap即可;如果是VectorDrawable这类非BitmapDrawable,需要先绘制到Bitmap上。

保存代码:

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putParcelable("item", item)
    
    // 把Drawable转成Bitmap
    val bitmap = if (drawable is BitmapDrawable) {
        drawable.bitmap
    } else {
        val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        drawable.setBounds(0, 0, canvas.width, canvas.height)
        drawable.draw(canvas)
        bitmap
    }
    outState.putParcelable("drawable_bitmap", bitmap)
}

恢复代码:

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    item = savedInstanceState?.getParcelable("item") ?: item
    
    // 从Bundle取出Bitmap并转回Drawable
    savedInstanceState?.getParcelable<Bitmap>("drawable_bitmap")?.let { bitmap ->
        drawable = BitmapDrawable(resources, bitmap)
    }
    
    return super.onCreateDialog(savedInstanceState)
}

方案2:存储资源ID(仅适用于内置资源)

如果你的Drawable是项目res/drawable目录下的内置资源,直接存它的资源ID是最省内存、最高效的方式。

保存代码:

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putParcelable("item", item)
    
    // 存储Drawable对应的资源ID
    outState.putInt("drawable_res_id", R.drawable.your_target_drawable)
}

恢复代码:

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    item = savedInstanceState?.getParcelable("item") ?: item
    
    // 通过资源ID重新获取Drawable
    savedInstanceState?.getInt("drawable_res_id")?.let { resId ->
        drawable = resources.getDrawable(resId, theme)
    }
    
    return super.onCreateDialog(savedInstanceState)
}

方案3:转成字节数组存储(适合小图)

如果前两种方案都不适用,可以把Bitmap压缩成字节数组存入Bundle,不过这种方式序列化/反序列化开销较大,建议只用于小尺寸图片。

保存代码:

// 先封装一个Drawable转Bitmap的工具函数
private fun drawableToBitmap(drawable: Drawable): Bitmap {
    return if (drawable is BitmapDrawable) {
        drawable.bitmap
    } else {
        val bitmap = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        drawable.setBounds(0, 0, canvas.width, canvas.height)
        drawable.draw(canvas)
        bitmap
    }
}

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putParcelable("item", item)
    
    // 转成字节数组存入Bundle
    val bitmap = drawableToBitmap(drawable)
    val outputStream = ByteArrayOutputStream()
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
    outState.putByteArray("drawable_bytes", outputStream.toByteArray())
}

恢复代码:

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    item = savedInstanceState?.getParcelable("item") ?: item
    
    // 从字节数组恢复Drawable
    savedInstanceState?.getByteArray("drawable_bytes")?.let { bytes ->
        val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
        drawable = BitmapDrawable(resources, bitmap)
    }
    
    return super.onCreateDialog(savedInstanceState)
}

内容的提问来源于stack exchange,提问作者Mohammad Javad Habibpour

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 05:05:20