7

私のアプリには、毎秒更新される時間表示があります。秒フィールドに使用されるTextViewが変更されるたびに、[開発者向けオプション]->[サーフェス更新の表示]ツールが画面全体を点滅させます。私は周りを見回しましたが、実際にはこの質問を見つけることができます。これは、TextViewがウィンドウの少なくとも一部でリレーアウトを引き起こすのを防ぐ方法がないことを非常によく示しています。そのため、TextViewが独自のコンテナにラップされていることを確認しましたが、それでも同じ問題が発生します。setText()を呼び出すたびに、ビュー全体が点滅します。

私の階層は次のとおりです。

  • 断片
    • RelativeLayout(フラグメントルートビュー)
      • LinearLayout
        • RelativeLayout
          • 私の時間TextViews
      • めったに変更されない他のさまざまなビューコンポーネント

可能であればこれを修正したいと思います。可能であれば視聴回数を減らす必要があり、それに取り組む予定ですが、これはまだアプリから削除したい問題です。

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 に答える