我想以编程方式更改ImageView的背景,但是在单独的线程上的for / while循环中。在我的例子中,我在一个名为' lights'的ArrayList中有3560个ImageView。我希望在短暂延迟后改变循环中的每个背景,即每秒更改一次。
ArrayList<ImageView> lights = new ArrayList<>();
int numberOfLights = 3560;
我最初使用的是这段代码,但是有一个问题是&#39;我&#39;必须被声明为final,因为它是从内部类调用的,如果我需要for for循环那就不可能......
Handler h = new Handler();
for( int i = 0; i < numberOfLights; i++) {
h.postDelayed(new Runnable() {
@Override
public void run() {
lights.get(i).setBackgroundResource(R.drawable.light_white);
}
}, 1000);
}
因此我尝试使用全局变量:
Handler h = new Handler();
counter = 0;
for( ; counter < numberOfLights; counter++) {
h.postDelayed(new Runnable() {
@Override
public void run() {
lights.get(counter).setBackgroundResource(R.drawable.light_white);
}
}, 1000);
}
好像这个计数器被完全忽略了,即使计数器超过numberOfLights,h.postDelayed也会运行,我尝试使用Thread.sleep调用正常的Threads,导致只有&#39;只有创建视图层次结构的原始线程可以触及其视图&#39;并且还使用了runOnUiThread方法,但没有运气。
非常感谢任何帮助。
答案 0 :(得分:1)
对每个循环使用。它比传统循环更优雅,在这种情况下,你可以使局部变量最终
for(final ImageView light: lights) {
h.postDelayed(new Runnable() {
@Override
public void run() {
light.setBackgroundResource(R.drawable.light_white);
}
}, 1000);
}
另外,将处理程序定义为
Handler h = new Handler(Looper.getMainLooper());
为了在UI线程上运行代码
答案 1 :(得分:0)
只需创建一个新变量:
final int iCopy = i;
然后在Runnable中使用它。
Handler h = new Handler();
for( int i = 0; i < numberOfLights; i++) {
final int iCopy = i;
h.postDelayed(new Runnable() {
@Override
public void run() {
lights.get(iCopy).setBackgroundResource(R.drawable.light_white);
}
}, 1000);
}
但是,如果同时修改lights
,则可能无法避免IndexOutOfBoundsException。在这种情况下,范围检查或制作阵列或灯光的副本将解决您的问题。