在我的应用程序中,我有一个时间显示,每秒更新一次。每次用于秒字段的TextView更改时,Developer Options-> Show surface updates工具都会闪烁整个屏幕。我环顾四周,真的只能找到this question,这很好地说明了没有办法阻止TextView导致至少部分窗口重新布局。所以我肯定要验证我的TextView是否包装在他们自己的容器中,但我仍然有同样的问题。每次调用setText()都会导致整个视图闪烁。
我的层次结构如下:
如果可能,我想解决这个问题。如果可能的话,我确实需要尝试减少我的观看次数,我打算继续努力,但这仍然是我想从应用中删除的问题。
答案 0 :(得分:10)
当硬件加速打开时,显示曲面更新会闪烁整个屏幕,但这并不意味着整个窗口被重绘。您可以使用另一个选项,它可以显示硬件加速打开时屏幕的哪些部分被重新绘制(“显示GPU视图更新”)。
答案 1 :(得分:1)
我遇到了类似的问题,我正在更新一个定时器,每次都会导致测量通过。如果你有一些很难测量的东西,比如ListView,它会影响性能。在我的情况下,我有一个ListView在更新定时器时不需要更改大小,因此我创建了一个自定义ListView持有者来阻止该度量从级联到ListView。现在它运行顺利!
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;
}
}
}