在非UI线程中编辑Button颜色(Android)

时间:2014-12-18 15:13:36

标签: java android multithreading android-ui

我已经看到了一些类似的问题并获得了一些信息,但是他们不愿意告诉我足够让它发挥作用。

我想做的是做一个简单的节奏游戏,玩家定期点击一个按钮(即节拍)。我想通过按钮改变颜色来设置一种发送信号的方式,并且由于这将是定期重复的任务,我想使用带有调度方法的定时器对象。

但是,当我尝试调用此方法时,它告诉我,我无法在非UI线程中更改UI。我已经尝试了几种方法在主线程中编写一个方法,我可以从timer对象调用,但每次都得到相同的错误。我假设我对UI线程中的重要内容有错误的想法,所以我希望有人可以清除它。

这是我尝试过的一种方式的片段,只是为了显示我的代码是什么样的:

OnClickListener clickButton = new View.OnClickListener() {
public void onClick(View v) {
    if (startBeat == 0){
        startBeat = System.nanoTime();
        timerStart.scheduleAtFixedRate((new TimerTask()
        {
            public void run()
            {
                flashButton();
            }
        }), 0, beatTime);               
        timerEnd.schedule(new TimerTask()
        {
            public void run()
            {
                unflashButton();
            }
        }, beatTolerance*2, beatTime);              
        return;
    }
};

public void flashButton(){
    beatPrompt.setBackgroundColor(getResources().getColor(R.color.primary1transparent_very));
}
public void unflashButton(){
    beatPrompt.setBackgroundColor(getResources().getColor(R.color.primary1));
}

要清楚,这一切都包含在我的MainActivity类和OnCreate类中。

5 个答案:

答案 0 :(得分:2)

如果你正处于一项活动中,你需要做的就是使用runOnUiThread(),然后放置代码来改变那里的ui元素

public void flashButton(){
    runOnUiThread(new Runnable() {
            @Override
            public void run() {
                beatPrompt.setBackgroundColor(getResources().getColor(R.color.primary1transparent_very));
            }
        });
}

答案 1 :(得分:0)

在任何情况下,您都无法从非UI线程触摸UI对象。

您可以使用Handler.sendMessageDelayed

来完成您的意图

答案 2 :(得分:0)

UI只能被主线程触及。您应该通过handlerrunOnUiThread

在ui主题上发布您正在执行的操作

尝试与此相似的内容

timerStart.scheduleAtFixedRate((new TimerTask()
    {
        public void run()
        {
            //replace MainActivity with your activity
            //if inside a fragment use getActivity()
            MainActivity.this.runOnUiThread(new Runnable() {
               public void run() {
                flashButton();
               }
            });
        }
    }), 0, beatTime);    

答案 3 :(得分:0)

如果您在Activity中,可以使用runOnUiThread包围flashButton()。

...
runOnUiThread(new Runnable(){
  public void run(){
      flashButton();
  }
});

...

答案 4 :(得分:0)

使用android.os.Handler类。按如下方式更改您的代码:

private Handler handler=new Handler();

public void flashButton(){
    handler.post(new Runnable(){
        public void run(){
            beatPrompt.setBackgroundColor(getResources().getColor(R.color.primary1transparent_very));
        }
    });
}
public void unflashButton(){
    handler.post(new Runnable(){
        public void run(){
            beatPrompt.setBackgroundColor(getResources().getColor(R.color.primary1));
        }
    });
}