In my app I have a time display which updates every second. Each time the TextView used for the seconds field changes, the Developer Options->Show surface updates tool flashes the entire screen. I've looked around and can really only find this question which pretty well clarifies that there is no way to prevent the TextView from causing a relayout for at least part of the window. So I was sure to verify that my TextView's are wrapped in their own container but I still have the same issue. Every call to setText() causes the entire view to flash.
My hierarchy is as follows:
I would like to fix this if possible. I do need to try and reduce my view count if possible and I plan on working on it but this is still a problem I would like to remove from the app.
Show surface updates flashes the entire screen when hardware acceleration is on but it does not mean the entire window was redrawn. There is another option you can use that shows you exactly what part of the screen was redrawn when hardware acceleration is on ("Show GPU view updates").
I encountered a similar problem where I was updating a timer which caused a measure pass every time. If you have something that is expensive to measure, like a ListView, it affects performance. In my case, I had a ListView that didn't need to change size when the timer updated, so I made a custom ListView holder to stop the the measure from cascading down to the ListView. Now it runs smoothly!
public class CustomListviewHolderLayout extends FrameLayout {
public int currentWidth = 0;
public int currentHeight = 0;
public CustomListviewHolderLayout(Context context) {
super(context);
}
public CustomListviewHolderLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomListviewHolderLayout(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
//Debug Prints
String wMode = "";
switch(MeasureSpec.getMode(widthMeasureSpec)){
case MeasureSpec.AT_MOST:
wMode = "AT_MOST"; break;
case MeasureSpec.EXACTLY:
wMode = "EXACTLY"; break;
case MeasureSpec.UNSPECIFIED:
wMode = "UNSPECIFIED"; break;
default:
wMode = "";
}
String hMode = "";
switch(MeasureSpec.getMode(heightMeasureSpec)){
case MeasureSpec.AT_MOST:
hMode = "AT_MOST"; break;
case MeasureSpec.EXACTLY:
hMode = "EXACTLY"; break;
case MeasureSpec.UNSPECIFIED:
hMode = "UNSPECIFIED"; break;
default:
hMode = "";
}
Log.i("RandomCustomListViewHolder", "wMode = " + wMode + ", size = " + MeasureSpec.getSize(widthMeasureSpec));
Log.i("RandomCustomListViewHolder", "hMode = " + hMode + ", size = " + MeasureSpec.getSize(heightMeasureSpec));
//only remeasure child listview when the size changes (e.g. orientation change)
if(getChildCount() == 1){
if(((MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) ||
(MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST))
&&((MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) ||
(MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST))){
//check if height dimensions are different than before
int newWidth = MeasureSpec.getSize(widthMeasureSpec);
int newHeight = MeasureSpec.getSize(heightMeasureSpec);
if((newWidth != currentWidth) || (newHeight != currentHeight)){
//remeasure if different
Log.i("RandomCustomListViewHolder", "measuring listView");
View childView = getChildAt(0);
childView.measure(widthMeasureSpec, heightMeasureSpec);
currentWidth = newWidth;
currentHeight = newHeight;
this.setMeasuredDimension(newWidth, newHeight);
} else {
//still set this view's measured dimension
this.setMeasuredDimension(newWidth, newHeight);
}
} else {
//Specify match parent if one of the dimensions is unspecified
this.setMeasuredDimension(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
}
} else {
//view does not have the listview child, measure normally
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
currentWidth = 0;
currentHeight = 0;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With