照片绘图功能:旋转设备时笔触丢失问题求助
嘿,我知道你现在被旋转设备丢失绘制笔触的问题搞头疼了!你之前用的那个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
相关产品推荐
相关产品推荐

