如何在执行下一行代码之前强制视图重新绘制

我有一个LinearLayout,我想改变它的一个子视图(一个ImageButton)被点击时的背景颜色。 我能够做到这一点,但不是马上 – 改变不会在屏幕上发生,直到后来(我认为在onResume调用期间)。 我想了解如何在设置背景后强制布局重绘,然后执行下一行代码。 这里是我的OnClickListenerbutton的onClick方法:

public void onClick(View v) { LinearLayout parentLayout = (LinearLayout) v.getParent(); parentLayout.setBackgroundResource(R.color.my_color); SystemClock.sleep(1000); //ms } 

睡眠命令在那里testing重绘是在它之前还是之后进行的。 结果:之后。 关于这个主题的大多数问题(比如这里和这里 )都说在视图上使用invalidate()。 我已经使用了命令parentLayout.invalidate();parentLayout.postInvalidate(); ,和parentLayout.refreshDrawableState(); 在背景和睡眠线之间,都无济于事。 睡眠命令后重新绘制仍然发生。 任何人都可以告诉我如何立即做到这一点?

其他可能有用的信息:LinearLayout绑定到一个ListView的行,上面的OnClickListener是一个扩展SimpleCursorAdapter的自定义类,而不是活动本身。 (这样我可以为ListView中的每一行设置一个监听器。)

Solutions Collecting From Web of "如何在执行下一行代码之前强制视图重新绘制"

你可以尝试使用forceLayout()并在调用之后立即draw(canvas) 。 如果你没有覆盖onLayout()onMeasuredraw()onDraw() ,那么默认的实现将会运行。 唯一的问题是,你必须得到canvas或手动创build一个。

由于Android是专门devise用于避免在正常更新之外进行绘制的,因此强烈build议不要采用这种方法。 虽然你是正确的, invalidate()不会立即发生,但它是鼓励重绘的最安全和最好的方法。 如果您想处理更新之外的绘图,Android提供了一种使用SurfaceHolder类来完成绘图的方法。

好的,我终于find了解决这个问题的办法,很简单。 看来,问题只是在OnClickLIstener中执行可绘制的更改,当我应该一直在OnTouchListener中执行时。 如果我为我的button设置一个OnTouchListener,查找ACTION_DOWN,然后在其父布局上运行setBackgroundColor,则立即发生更改。

这个post是一个替代的,不太健壮的解决scheme。 您可以在xml中为父布局背景分配一个select器,然后在上面提到的OnTouchListener中,在该布局上运行setPressed(true)。 这不是一个好的解决scheme,因为select器比直接更改代码中的视图属性的自由度要less得多。 例如,您不能通过按不同的button来将布局背景设置为不同的颜色。

感谢那些对此提出的build议!

进行更改并调用listview.invalidate(); 以反映UI上的这些变化