【问题标题】:android updating view from a thread. Only the original thread that created the view can touch its views.android 从线程更新视图。只有创建视图的原始线程才能接触其视图。
【发布时间】:2015-03-06 23:03:26
【问题描述】:

我知道这似乎是一个菜鸟问题,但我已经尝试了所有方法。我想动画一个数字递增。所以我设置了一个视图。我在视图中创建了一个循环一定次数的线程。在循环中,我调用 Thread.sleep,然后增加一个数字。但是我不确定每次通过循环时如何调用 invalidate() 方法来更新视图。我尝试了回调,但这不起作用。您的帮助将不胜感激。我要增加的是使用 textPaint 绘制的“centerText”

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();
}



}

【问题讨论】:

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


    【解决方案1】:

    内调用的任何东西

      new Thread(new Runnable(){
      ...
      }
    

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-26
      • 1970-01-01
      • 2016-01-17
      • 1970-01-01
      • 2015-05-22
      • 2018-05-30
      相关资源
      最近更新 更多