如何在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
相关产品推荐
相关产品推荐

