Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force a view to redraw immediately before the next line of code is executed

Tags:

I have a LinearLayout that I would like to change the background color of when one of its child views (an ImageButton) is clicked. I am able to do this, but not immediately - the change doesn't occur on the screen until later (I think during an onResume call). I would like to find out how to force the layout to redraw after the background is set, before the next line of code executes. Here is the onClick method of my OnClickListener for the button:

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

The sleep command is in there to test whether the redraw happens before or after it. The result: after. Most questions on this topic (like here and here) say to use invalidate() on the view. I have used the commands parentLayout.invalidate();, parentLayout.postInvalidate();, and parentLayout.refreshDrawableState(); in between the background and sleep lines, all to no avail. The redraw still happens after the sleep command. Can anyone tell me how to make it happen immediately?

Other possibly useful information: The LinearLayout is bound to the rows of a ListView, and the OnClickListener above is in a custom class that extends SimpleCursorAdapter, not in the activity itself. (This way I can set a listener for each of the rows in the ListView.)

like image 358
pvans Avatar asked Jan 06 '12 07:01

pvans


People also ask

How do I force redraw a view?

Invoking invalidate() on a View causes it to draw itself via the View. You should check this out: http://developer.android.com/guide/topics/ui/custom-components.html. A TextView internally invalidates itself when you invoke setText() and redraws itself with the new text set via the setText() call.


1 Answers

You might try forceLayout() with a call to draw(canvas) immediately after. If you did not override onLayout(), onMeasure, draw() or onDraw(), then the default implementation will run. The only issue with this is that you have to either get the Canvas or create one manually.

It is strongly discouraged to pursue this approach as Android is specifically designed to avoid drawing outside of normal updates. While you are correct that invalidate() does not happen immediately, it is the safest and best way to encourage a redraw. If you want to handle drawing outside of updates, Android provides a way to do that with the SurfaceHolder class.

like image 151
Fuzzical Logic Avatar answered Sep 19 '22 06:09

Fuzzical Logic