52

私のアプリケーションでは、ビューの onMeasure() オーバーライドの 1 つに無限ループがあります。onMeasure のブレークポイントからソース コードをデバッグすると、ViewRoot によって呼び出される PhoneWindow$DecorView の measure() (View Hierarchy の最上位クラス) までスタック トレースをたどることができます。 .performTraversals()。ここからステップオーバーを続けると、最終的に PhoneWindow$DecorView の measure() が Looper.loop() クラスのメッセージによって再度呼び出されます。無効化のように、何かが再測定が必要なメッセージをキューに入れていると思います。

私の質問は、メジャー呼び出しがビューで発生する必要があるトリガーは何ですか?

レイアウト/測定/描画プロセスの私の理解から、これは特定のビューで無効化()メソッドが呼び出された場合にのみ発生し、それはトリクルダウンしてそのビューのレイアウト/測定/描画パスを無効にし、すべてを実行しますその子供たち。どういうわけか、ビュー階層の最上位のビューが無効になっていると思います。

ただし、私が持っているすべての無効化呼び出しに明示的にブレークポイントを設定しており、invalidate を無限に呼び出しているわけではありません。ですから、そうではないと思います。測定パスをトリガーする別の方法はありますか? 内部で何かがこれを引き起こしている可能性はありますか? 無限を無効にするものは何もないことを知った後、私はちょっとアイデアがありません。

4

2 に答える 2

89

カスタム ビューのメジャー パスをトリガーするには、requestLayout() メソッドを呼び出す必要があります。たとえば、View を拡張するカスタム ビューを実装していて、それが TextView のように動作する場合、setText メソッドを次のように記述できます。

/**
 * Sets the string value of the view.
 * @param text the string to write
 */
public void setText(String text) {
    this.text = text;

            //calculates the new text width
    textWidth = mTextPaint.measureText(text);

    //force re-calculating the layout dimension and the redraw of the view
    requestLayout();
    invalidate();
}
于 2012-12-15T12:58:08.867 に答える