0

我想制作一个看起来好像一个点/圆在屏幕上水平移动的视图。我只想通过自定义视图来实现这一点。所以我写了一段代码,我想在其中调用 onDraw() 来绘制一个圆圈,然后它会调用一个处理程序,它将等待 500 毫秒并调用 onDraw()。所以每次调用 onDraw() 时,circle 都会向右移动几步。但在这里我无法在 run() 和 onDraw() 之间同步调用。代码:

package com.example.layoutpractice;

import javax.net.ssl.HandshakeCompletedListener;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff.Mode;
import android.os.Build;
import android.os.Handler;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;

public class DrawView extends View {
    private static final String TAG = "DrawView";
    Context ctx = null;
    int MAX_WIDTH = 0;
    int MAX_HEIGHT = 0;
    int current_x = 0;
    int current_y = 0;
    Paint paint = null;

    public DrawView(Context context) {

    @TargetApi(13)
    private void initialize() {
        // get the screen size
        WindowManager wm = (WindowManager) ctx
                .getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
            display.getSize(size);
            MAX_WIDTH = size.x;
            MAX_HEIGHT = size.y;
        } else {
            MAX_WIDTH = display.getWidth();
            MAX_HEIGHT = display.getHeight();
        }

        // initialize paint
        paint = new Paint();
        paint.setColor(Color.BLUE);
        this.setFocusable(true);
        this.setFocusableInTouchMode(true);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Log.d(TAG, "onDraw()");
        current_y = MAX_HEIGHT / 2;
        while (current_x < MAX_WIDTH) {
            canvas.drawColor(Color.WHITE, Mode.CLEAR);
            canvas.drawCircle(current_x, current_y, 2, paint);
            current_x = current_x + 10;
            // new Thread(new TimeHandler()).start();
            new TimeHandler().execute();
        }
        super.onDraw(canvas);
    }

    class TimeHandler extends Handler {
        Runnable myRun = new Runnable() {
            public void run() {
                Log.d(TAG, "run");
                invalidate();
            }
        };

        public void execute() {
            this.postDelayed(myRun, 500);
        }

    }
}

日志

02-17 01:40:28.355: D/DrawView(1162): onDraw()
02-17 01:40:28.875: D/DrawView(1162): run
02-17 01:40:28.875: D/DrawView(1162): run
02-17 01:40:28.875: D/DrawView(1162): run
02-17 01:40:28.875: D/DrawView(1162): run
02-17 01:40:28.966: D/DrawView(1162): onDraw()
02-17 01:40:28.966: D/DrawView(1162): run
02-17 01:40:28.966: D/DrawView(1162): run
02-17 01:40:28.966: D/DrawView(1162): run
02-17 01:40:28.966: D/DrawView(1162): run
02-17 01:40:29.005: D/DrawView(1162): run
02-17 01:40:29.005: D/DrawView(1162): run
02-17 01:40:29.005: D/DrawView(1162): run
02-17 01:40:29.005: D/DrawView(1162): run
02-17 01:40:29.005: D/DrawView(1162): run
02-17 01:40:29.005: D/DrawView(1162): run
02-17 01:40:29.036: D/DrawView(1162): run
02-17 01:40:29.036: D/DrawView(1162): run
02-17 01:40:29.036: D/DrawView(1162): run
02-17 01:40:29.036: D/DrawView(1162): run
02-17 01:40:29.036: D/DrawView(1162): run
02-17 01:40:29.036: D/DrawView(1162): run
02-17 01:40:29.065: D/DrawView(1162): run
02-17 01:40:29.065: D/DrawView(1162): run
02-17 01:40:29.075: D/DrawView(1162): run
02-17 01:40:29.075: D/DrawView(1162): run
02-17 01:40:29.101: D/DrawView(1162): run
02-17 01:40:29.101: D/DrawView(1162): run
02-17 01:40:29.101: D/DrawView(1162): run
02-17 01:40:29.101: D/DrawView(1162): run
02-17 01:40:29.101: D/DrawView(1162): run
02-17 01:40:29.101: D/DrawView(1162): run
02-17 01:40:29.101: D/DrawView(1162): run
02-17 01:40:29.101: D/DrawView(1162): run
02-17 01:40:29.101: D/DrawView(1162): run
02-17 01:40:29.101: D/DrawView(1162): run
02-17 01:40:29.101: D/DrawView(1162): run
02-17 01:40:29.105: D/DrawView(1162): onDraw()
02-17 01:40:29.125: D/DrawView(1162): run
02-17 01:40:29.125: D/DrawView(1162): run
02-17 01:40:29.125: D/DrawView(1162): run
02-17 01:40:29.125: D/DrawView(1162): run
02-17 01:40:29.125: D/DrawView(1162): run
02-17 01:40:29.125: D/DrawView(1162): run
02-17 01:40:29.125: D/DrawView(1162): run
02-17 01:40:29.125: D/DrawView(1162): run
02-17 01:40:29.125: D/DrawView(1162): run
02-17 01:40:29.125: D/DrawView(1162): run
02-17 01:40:29.125: D/DrawView(1162): run
02-17 01:40:29.125: D/DrawView(1162): run
02-17 01:40:29.125: D/DrawView(1162): run
02-17 01:40:29.175: D/DrawView(1162): onDraw()
4

1 回答 1

0

改变

while (current_x < MAX_WIDTH)

if (current_x < MAX_WIDTH)

PS你的设计是错误的。onDraw 是一个特殊的方法,它可以被android调用,而不仅仅是你。每次您通过 invalidate 或框架本身调用 onDraw 时,您都会安排一个 runnable 在 500 毫秒内运行。而且您认为 onDraw 将每 500 毫秒执行一次(current_x = current_x + 10;)...您有问题)

要解决您的问题,请不要在 ondraw 中添加任何逻辑。OnDraw 应该只使用当前状态绘制视图。只留下这个:

    current_y = MAX_HEIGHT / 2;
    canvas.drawColor(Color.WHITE, Mode.CLEAR);
    canvas.drawCircle(current_x, current_y, 2, paint);

    super.onDraw(canvas);

在您的自定义视图中创建其他方法,该方法应执行以下操作:

public void startBallMovement() {
      animationRunnable.run();
}

private Handler handler = new Handler();
private final Rubbanle animationRunnable = new Runnable() {
     public void run() {
         current_x = current_x + 10;
         if (current_x < MAX_WIDTH) {
             handler.postDelayed(animationRunnable, 500);
         }
         invalidate();
     }
}

我确信您可以按原样使用我的代码,但逻辑很清楚。

于 2013-02-16T21:20:44.463 回答