android从一个线程更新视图。只有创建视图的原始线程才能触及其视图。

时间:2015-03-06 23:03:26

标签: android multithreading android-animation android-custom-view

我知道这可能看起来像一个菜鸟问题,但我已经尝试了一切。我想动画一个数字递增。所以我建立了一个观点。我在视图中创建了一个循环一定次数的线程。在循环中我调用Thread.sleep然后我增加一个数字。但是,我不确定如何调用invalidate()方法在每次循环时更新视图。我尝试过回调,但这不起作用。非常感谢您的帮助。我试图增加的是' centerText'这是使用textPaint

绘制的
public class GameView extends View {

private int backgroundColor;
private int circleColor;
private int radiusFactor;
private Paint circlePaint;
private Paint textPaint;
private Paint text2Paint;
private Paint text3Paint;
private String topMessage;
private String bottomMessage;
private String topMessage2;
private String bottomMessage2;
private String centerText;
private boolean isRunning = false;
private int FPS = 60;

public interface animateThread{
    public void updateUI(String text);
}

private animateThread threadCheck = new animateThread(){
    @Override
    public void updateUI(String text) {
        centerText="text";
        invalidate();
    }
};


public GameView(Context context) {
    super(context);

    backgroundColor = Color.parseColor("#FF4000");
    circleColor = Color.parseColor("#B40404");
    radiusFactor = 4;

    centerText="?";

    circlePaint = new Paint();
    circlePaint.setAntiAlias(true);
    circlePaint.setColor(circleColor);

    textPaint = new Paint();
    textPaint.setAntiAlias(true);
    textPaint.setColor(Color.WHITE);
    textPaint.setTextAlign(Paint.Align.CENTER);

    text2Paint = new Paint();
    text2Paint.setAntiAlias(true);
    text2Paint.setColor(Color.BLACK);
    text2Paint.setTextAlign(Paint.Align.CENTER);

    text3Paint = new Paint();
    text3Paint.setAntiAlias(true);
    text3Paint.setColor(Color.BLACK);
    text3Paint.setTextAlign(Paint.Align.CENTER);

    topMessage = "One in a";
    topMessage2="Hundred?";
    bottomMessage="Click the Circle";
    bottomMessage2="To find out";
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            break;
        case MotionEvent.ACTION_UP:

            break;
        case MotionEvent.ACTION_MOVE:
            break;

    }
    if(!isRunning) startAnimation(threadCheck);

    return true;
}

@Override
protected void onDraw(Canvas canvas) {
    setBackgroundColor(backgroundColor);

    textPaint.setTextSize(getWidth()/4);
    text2Paint.setTextSize(getWidth()/6);
    text3Paint.setTextSize(getWidth()/8);

    canvas.drawCircle(getWidth()/2, getHeight()/2,getWidth()/radiusFactor,  
circlePaint);
    canvas.drawText(centerText, getWidth()/2, getHeight()/2- 
((textPaint.descent()+textPaint.ascent())/2), textPaint);

    canvas.drawText(topMessage, getWidth()/2, ((getHeight()/2-
getWidth()/radiusFactor)/2+((text2Paint.descent()+text2Paint.ascent())/2)),  
text2Paint);
    canvas.drawText(topMessage2, getWidth()/2, (getHeight()/2-
getWidth()/radiusFactor)/2-((text2Paint.descent()+text2Paint.ascent())), 
text2Paint);

    canvas.drawText(bottomMessage, getWidth()/2, getHeight()*4/5+
((text3Paint.descent()+text3Paint.ascent())/2), text3Paint);
    canvas.drawText(bottomMessage2, getWidth()/2, getHeight()*4/5-   
((text3Paint.descent()+text3Paint.ascent())), text3Paint);

}

public void startAnimation(final animateThread mCallback) {
    Thread animate = new Thread(new Runnable(){

        @Override
        public void run() {
            isRunning=true;
            int count=0;
            for (int i=0;i<FPS*5;i++) {
                count++;
                if(count>100) count = 1;
                mCallback.updateUI(count+"");
                try {
                    Thread.sleep(1000/FPS);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            isRunning=false;
        }
    });
    animate.start();
}



}

1 个答案:

答案 0 :(得分:1)

中调用的任何内容
  new Thread(new Runnable(){
  ...
  }

将隐式运行在非UI线程上。如果要触摸UI,必须强制该任务的代码在UI线程上运行,如下所示:

context.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        updateUI(count+"");
    }
});