需要在处理程序和onDraw()之间同步

时间:2013-02-16 20:37:26

标签: android view handler

我想制作一个视图,表明一个点/圆在屏幕上水平移动。 我想通过自定义视图实现此目的。 所以我写了一段代码,我想调用onDraw(),它将绘制一个圆圈,然后它将调用一个处理程序,它将等待500ms并调用onDraw()。所以每次调用onDraw()时,圆圈都会向右移动几步。 但是在这里我无法在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()

1 个答案:

答案 0 :(得分:0)

更改

while (current_x < MAX_WIDTH)

if (current_x < MAX_WIDTH)

P.S。你设计错了。 onDraw是一种特殊方法,可以由android调用,而不是由你调用。每次onDraw由您通过invalidate或框架本身调用时,您都会安排runnable在500ms内运行。并且你认为onDraw将每500ms执行一次(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();
     }
}

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