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

照片绘图功能:旋转设备时笔触丢失问题求助

嘿,我知道你现在被旋转设备丢失绘制笔触的问题搞头疼了!你之前用的那个getLastNonConfigurationInstance()方法确实已经被废弃了,而且可靠性也不如现在的新方案,我给你两个靠谱的解决思路,都是谷歌官方推荐的:

方案一:用ViewModel保存绘制状态(首推)

ViewModel是专门用来处理配置变化(比如屏幕旋转)时的UI状态保存的,它在Activity重建时不会被销毁,数据可以直接复用,完全避开了序列化的麻烦。

步骤1:创建ViewModel类

先定义一个ViewModel来存储你的绘制数据,建议保存**路径列表(Path)**而不是Bitmap,因为Path更轻量,内存占用小:

// Kotlin版本
class DrawingViewModel : ViewModel() {
    // 存储所有绘制的路径
    var drawingPaths: MutableList<Path>? = null
}
// Java版本
public class DrawingViewModel extends ViewModel {
    private List<Path> drawingPaths;

    public List<Path> getDrawingPaths() {
        return drawingPaths;
    }

    public void setDrawingPaths(List<Path> drawingPaths) {
        this.drawingPaths = drawingPaths;
    }
}

步骤2:在Activity中关联ViewModel并恢复数据

在Activity的onCreate方法中获取ViewModel,旋转后直接从ViewModel里取出路径恢复绘制:

// Kotlin版本
private lateinit var viewModel: DrawingViewModel
private lateinit var yourCustomDrawView: CustomDrawView // 你的自定义绘制View

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    
    // 初始化ViewModel
    viewModel = ViewModelProvider(this)[DrawingViewModel::class.java]
    yourCustomDrawView = findViewById(R.id.custom_draw_view)
    
    // 旋转后恢复绘制路径
    viewModel.drawingPaths?.let {
        yourCustomDrawView.setDrawingPaths(it)
        yourCustomDrawView.invalidate() // 通知View重绘
    }
}
// Java版本
private DrawingViewModel viewModel;
private CustomDrawView yourCustomDrawView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    viewModel = new ViewModelProvider(this).get(DrawingViewModel.class);
    yourCustomDrawView = findViewById(R.id.custom_draw_view);
    
    // 恢复绘制路径
    if (viewModel.getDrawingPaths() != null) {
        yourCustomDrawView.setDrawingPaths(viewModel.getDrawingPaths());
        yourCustomDrawView.invalidate();
    }
}

步骤3:实时保存绘制状态

在用户每次完成一笔绘制时,或者在Activity即将进入后台时,把当前的路径列表保存到ViewModel:

// 在自定义View中添加获取路径的方法
fun getDrawingPaths(): MutableList<Path> {
    return this.drawingPaths // 假设你在自定义View中用这个列表存储所有路径
}

// 在Activity中调用保存
private fun saveDrawingState() {
    viewModel.drawingPaths = yourCustomDrawView.getDrawingPaths()
}

// 可以在onPause或者每次绘制结束后调用saveDrawingState()
override fun onPause() {
    super.onPause()
    saveDrawingState()
}
方案二:用onSaveInstanceState保存数据

如果你的绘制数据量不大,也可以用Activity的onSaveInstanceState方法来保存,适合小数据场景(比如少量路径):

步骤1:保存数据到Bundle

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    // 把路径列表存入Bundle,注意Path需要序列化,这里可以用Parcelable集合
    outState.putParcelableArrayList("drawing_paths", ArrayList(yourCustomDrawView.getDrawingPaths()))
}

步骤2:从Bundle恢复数据

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    
    yourCustomDrawView = findViewById(R.id.custom_draw_view)
    
    if (savedInstanceState != null) {
        val savedPaths = savedInstanceState.getParcelableArrayList<Path>("drawing_paths")
        savedPaths?.let {
            yourCustomDrawView.setDrawingPaths(it)
            yourCustomDrawView.invalidate()
        }
    }
}

⚠️ 注意:如果要保存Bitmap的话,不建议用Bundle,因为Bundle有大小限制,容易抛出异常,还是用ViewModel更稳妥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:46:39