2

アクティビティにアニメーション画像を追加したいと思います: 軌跡 (黒い線) を移動する白い円だけです。

ここに画像の説明を入力

それを行う最良の方法は何ですか?

  1. アニメーションを翻訳
  2. フレームアニメーション
  3. キャンバス

実装は次のようになります。

  1. 白い円は、背景が透明な小さな ImageView です。別の ImageView (黒い曲線) の上に配置されます。
  2. FrameAnimation: 円の位置ごとに、アニメーションのフレームである画面全体の個別の png イメージがあります。
  3. 白い点が動くたびに drawCircle() と restoreBackgroundImage() を使用します。

これまでに FrameAnimation を試しましたが、10 フレームだけ outOfMemoryError が発生しました。

4

1 に答える 1

0

次のコードは、そのCanvas方法を実装しています。効率的で OOM なし。Path軌道をオブジェクトに変更するだけです。

public class TestView extends View {
    private Path path;
    private Paint pathPaint;
    private Paint dotPaint;
    private long beginTime;
    private long duration = 3000;
    private float dotRadius = 3;
    private PathMeasure pm;

    public TestView(Context context) {
        super(context);
        init();
    }

    public TestView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public TestView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        path = new Path();
        path.moveTo(0, 100);
        path.lineTo(100, 200);
        path.lineTo(200, 50);
        //TODO: Put your path here

        pm = new PathMeasure(path, false);
        pathPaint = new Paint();
        pathPaint.setARGB(255, 0, 0, 0);
        pathPaint.setStrokeWidth(2);
        pathPaint.setStyle(Paint.Style.STROKE);
        dotPaint = new Paint();
        dotPaint.setARGB(255, 255, 255, 255);
        dotPaint.setStyle(Paint.Style.FILL);
        beginTime = 0;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawARGB(0, 0, 0, 0);
        canvas.drawPath(path, pathPaint);

        long currentTime = System.currentTimeMillis();
        float currentDistance;

        if (beginTime == 0) {
            beginTime = currentTime;
            currentDistance = 0;
        } else if (beginTime > 0 && currentTime - beginTime < duration) {
            currentDistance = (float) (currentTime - beginTime) / (float) duration * pm.getLength();
        } else {
            beginTime = -1;
            return;
        }

        float pos[] = new float[2];
        pm.getPosTan(currentDistance, pos, null);
        canvas.drawCircle(pos[0], pos[1], dotRadius, dotPaint);
        invalidate();
    }
}
于 2015-08-05T05:30:41.840 に答える