Android Studio MVP架构下实现绘制调用的逐帧动画
MVP架构下迷宫逐帧绘制动画实现方案
核心思路:状态驱动+View主动刷新
因为MVP要求Presenter不能直接操作View的Canvas,所以得把绘制逻辑交回给View,Presenter只负责维护绘制状态和控制动画节奏。
- 拆分求解路径为步骤列表:在Presenter完成迷宫求解后,把整个路径拆成单个单元格的坐标列表,保存起来,同时维护
currentDrawStep变量记录当前绘制到哪一步。 - 定义View交互接口:在你的
MazeView接口里新增refreshMaze()方法,View实现这个方法时,从Presenter获取当前currentDrawStep和路径列表,只绘制到对应步骤的单元格。 - 用定时任务控制动画节奏:在Presenter里用
Handler(Java)或者Coroutine(Kotlin)做定时循环,每次间隔(比如200ms)就把currentDrawStep加1,然后调用view.refreshMaze(),直到所有步骤绘制完成。
代码示例(Java版)
Presenter部分
public class MazePresenter { private MazeView view; private List<Point> solutionSteps; private int currentDrawStep = 0; private Handler drawHandler = new Handler(Looper.getMainLooper()); private boolean isSolving = false; // 迷宫求解完成后启动动画 private void startDrawAnimation() { isSolving = true; currentDrawStep = 0; drawHandler.postDelayed(drawRunnable, 200); } private Runnable drawRunnable = new Runnable() { @Override public void run() { if (currentDrawStep < solutionSteps.size()) { view.refreshMaze(); currentDrawStep++; drawHandler.postDelayed(this, 200); } else { isSolving = false; } } }; // 给View提供获取绘制状态的方法 public List<Point> getSolutionSteps() { return solutionSteps; } public int getCurrentDrawStep() { return currentDrawStep; } public boolean isSolving() { return isSolving; } // View销毁时移除回调,避免内存泄漏 public void onDestroy() { drawHandler.removeCallbacks(drawRunnable); } }
View(DrawingView)部分
public class DrawingView extends View implements MazeView { private MazePresenter presenter; @Override public void refreshMaze() { invalidate(); // 触发重绘,onDraw中根据Presenter状态绘制 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 先绘制迷宫背景 drawMazeBackground(canvas); // 绘制到当前步骤的求解路径 List<Point> steps = presenter.getSolutionSteps(); int currentStep = presenter.getCurrentDrawStep(); for (int i = 0; i < currentStep; i++) { Point p = steps.get(i); drawCell(canvas, p.x, p.y, Color.RED); // 绘制单个路径单元格 } } }
代码优化建议
- 迷宫清除优化:不要用彩色方块覆盖,而是维护
Cell[][] mazeCells数组,每个Cell记录是否为墙、是否是路径等状态,清除迷宫时直接重置数组状态,再调用refreshMaze(),View根据数组状态绘制,效率更高。 - 求解状态控制:用
isSolving布尔值标记当前是否在绘制动画,点击生成/求解按钮时先判断presenter.isSolving(),如果为true直接返回,避免重复触发。
内容的提问来源于stack exchange,提问作者Tyoh
相关产品推荐
相关产品推荐

