7

在我的应用程序中,我有一个每秒更新的时间显示。每次用于秒字段的 TextView 更改时,开发人员选项->显示表面更新工具都会闪烁整个屏幕。我环顾四周,真的只能找到这个问题,它很好地阐明了没有办法阻止 TextView 导致至少部分窗口重新布局。所以我确定要验证我的 TextView 是否包装在它们自己的容器中,但我仍然遇到同样的问题。每次调用 setText() 都会导致整个视图闪烁。

我的层次结构如下:

  • 分段
    • 相对布局(片段根视图)
      • 线性布局
        • 相对布局
          • 我的时间文本视图
      • 其他很少更改的视图组件

如果可能的话,我想解决这个问题。如果可能的话,我确实需要尝试减少我的查看次数,并且我计划继续努力,但这仍然是我想从应用程序中删除的问题。

4

2 回答 2

10

当硬件加速打开时,显示表面更新会闪烁整个屏幕,但这并不意味着整个窗口都被重绘了。您可以使用另一个选项来准确显示在硬件加速开启时屏幕的哪一部分被重绘(“显示 GPU 视图更新”)。

于 2013-01-08T19:40:43.403 回答
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;
        }
    }
}
于 2014-03-11T20:27:16.253 回答