Search code examples
androidkotlinandroid-drawable

Does View gets redrawn when property programatically changed to same value?


Let's have some View in fragment (e.g. LinearLayout or ImageView). If I change property of this View programatically (e.g. change backgroundColor) to same property that is already set, is view redrawn/rerendered?

Example of double set:

binding.someLinearLayout.setBackgroundColor(redColor)
binding.someLinearLayout.setBackgroundColor(grayColor);
binding.someLinearLayout.setBackgroundColor(grayColor);
binding.someLinearLayout.setBackgroundColor(grayColor);

LinearLayout will be redrawn twice or 4 times? If 4 times, should I implement something like this to prevent it?

fun setBackgroundColor(ll: LinearLayout, color: Int){
   val current = binding.progressBarChunk4.background as ColorDrawable
   if(current.getColor() != color)
      ll.setBackgroundColor(color)
}

setBackgroundColor(binding.someLinearLayout, redColor); // Color set
setBackgroundColor(binding.someLinearLayout, grayColor); // Color set
setBackgroundColor(binding.someLinearLayout, grayColor); // ignored
setBackgroundColor(binding.someLinearLayout, grayColor); // ignored

So basically I am asking if multiple set of same property affects performance, because view gets redrawn everytime.


Solution

  • If you call setBackgroundColor four times in a row like that, it doesn't cause four redraws. The view is only redrawn one time on the next loop of the main thread, after your current function has returned.

    Changing these properties usually does invalidate the view, so your first call to setBackgroundColor will trigger a redraw on the next loop of the main thread, even if it matches the existing color. I can't guarantee that's true of every existing property in the core Views, because I haven't checked them all. It is definitely true for setBackgroundColor and setText.

    Your defensive check of the current color could potentially prevent an unnecessary redraw, but only if you ultimately don't mutate any views in this iteration of your main thread. I can't think of a case where it would be worth worrying about. If this is in onCreate() or onViewCreated(), the view hasn't been drawn yet anyway. If this is in a click listener, your view is getting redrawn anyway because your button's visual state is changing.

    It might be worth doing defensive checks for changes that affect the size of the view, because then you could be preventing a re-layout. But probably only if this happening during some animation, because otherwise the savings would not be noticeable.