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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 21:55:21