2011-09-06 134 views
0

我需要从循环更新的Android按钮,使每个按钮高亮逐一
enter image description here如何在循环中更新循环中的Android UI元素?

我试图使用的AsyncTask没有成功,同样与处理程序。
处理程序下面的例子[从代码的一部分,只给你举例]:

for(i=1;i<10;i++){ 
final int value = i; 
Runnable runnable = new Runnable() { 
    @Override 
    public void run() { 
      try { 
       Thread.sleep(0); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      handler.post(new Runnable() { 
       @Override 
       public void run() { 
        Button currentButton = (Button) findViewById(value); 
        currentButton.setPressed(true); 

       } 
      }); 
    } 
}; 
new Thread(runnable).start(); 

任何想法如何到达用户界面元素逐一?
又如:例如在标准循环如下:
- 通过ID获得按钮
- setPressed(真),使按钮高亮
- 执行想要的功能
- setPressed(假的),只有当先前的一步完成。
问题:在运行按钮的循环没有更新,只有当循环结束后,在此情况下,用户不会明白什么步骤执行:
下面的代码是开始,所有环路的事件:

View.OnClickListener OnClickDoSomething(final Button button) { 
return new View.OnClickListener() { 
    public void onClick(View v) { 
     button.setText("text now set.. "); 
     UpdateStep updateStep; 
     for(int i=1; i<stepsArray.size();i++) 
     { 
     final int value = i; 
     Button currentButton = (Button) findViewById(i); 
     currentButton.setHighlightColor(0x7f050003); 
     currentButton.setPressed(true); 

     for(int x=0;x<900000;x++); // will be replaced with the real function 

     currentButton.setPressed(false); 
     } 
    } 
}; 
+0

您应该首先了解*为什么*您的应用程序在循环中时UI不会更新。接下来,您应该(如您第一次尝试的那样)学习如何异步运行代码,即在单独的线程上运行代码。 –

+1

@Ed - 这不是在UI线程上运行。注意发布代码的最后一行? –

+0

@Ted:....... d'噢。好吧,它运行得太快了。 –

回答

1

你正在零时间睡觉。尝试将循环中的睡眠延迟增加到您会注意到延迟的地方。您可能还需要使显示无效以使其刷新(尽管我认为按钮会在按下状态更改时自动执行此操作)。

另一种方法是使用Handler的postDelayedpostAtTime方法在未来发布10个更新点的更新,每个更新会逐渐进入未来,并从您的循环中完全消除睡眠。

你忘记取消上一个按钮吗?

编辑:你一次启动10个线程,它们以未指定的顺序执行。启动一个单线程并将该循环放入线程的运行方法中。

+0

感谢您的回答,每个按钮都会在我的真实代码中执行很多http请求,睡眠或延迟不会有帮助,因为我只想在http请求完成运行时离开按钮,然后解除按钮并移到下一个[附加的代码不是我真实的代码,只是例子] – kimo

+0

明白了。在附加到原始文章的示例中,我认为,问题是您正在UI线程(在OnClickListener中)上执行所有昂贵的执行。应该将其移至工作线程,或者使用AsyncTask或您创建的线程。 –

0

您确定此代码没有崩溃。使用1到10之间的ID来获取视图对我来说看起来不好;)。您通常应该使用R.id类的整数。

其次你一定要用Handler s代替Thread。看看postDelayed方法。

+0

按钮是动态创建的,我设置了每个按钮的ID,并且它正在工作。 – kimo

0

为什么您使用ThreadHandler与对方! 我认为这段代码会更准确:

 for (int i = 1; i < 10; i++) { 
      final int value = i; 
      Runnable runnable = new Runnable() { 
       @Override 
       public void run() { 
        Button currentButton = (Button) findViewById(value); 
        currentButton.setPressed(true); 

       } 
      }; 
      handler.postDelayed(runnable, 50); 
     } 
+0

那不行。它将在循环运行后大约50毫秒的时间内运行所有可运行的程序。如果你做了'handler.postDelayed(runnable,500 * i)''',它会起作用。 –

+0

据我所知,它不会,它将延迟50从处理程序收到的最后一条消息,我会尝试它,如果我有时间,并告诉你结果,但我已经有一个代码告诉我,但不当然,因为我没有实现它 –