1

以下を実装するカスタム ビューを作成しましたonMeasure

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    float width = MeasureSpec.getSize(widthMeasureSpec);
    final int widthMode = MeasureSpec.getMode(widthMeasureSpec);

    float height = MeasureSpec.getSize(heightMeasureSpec);
    final int heightMode = MeasureSpec.getMode(heightMeasureSpec);

    float nominalHeight = getResources().getInteger(R.integer.nominalheight);
    float nominalWidth = getResources().getInteger(R.integer.nominalwidth);

    float aspectRatio = nominalWidth / nominalHeight;

    if( width / height > aspectRatio //too wide
            && (
                    widthMode == MeasureSpec.AT_MOST ||
                    widthMode == MeasureSpec.UNSPECIFIED 
            )
            ) { 
        width -= (width - height * aspectRatio);
    }
    if( width / height < aspectRatio //too tall
            && (
                    heightMode == MeasureSpec.AT_MOST ||
                    heightMode == MeasureSpec.UNSPECIFIED 
            )
            ) { 
        height -= (height - width / aspectRatio);
    }

    setMeasuredDimension((int)width, (int)height);
}

意図は、可能であれば、 および で指定されたものと同じ縦横比を持つ長方形を作成することnominalheightですnominalwidth。明らかに、関数が渡された場合MeasureSpec.EXACTLY、その方向に指定された次元でレイアウトする必要があります。

これをViewxmlWRAP_CONTENTで両方向に配置しています。私を困惑させているのは、onMeasure 呼び出しをステップ実行すると、半分が MeasureSpec.AT_MOST を示し、ルーチンが正しい長方形を計算し、残りの半分が MeasureSpec.EXACTLY を示し、明らかに指定された寸法を使用することです。さらに不可解なことに、条件を無効にすると (ドキュメントサンプルコードから、間違っていると思います)、正常に動作します。

異なる値でこれらの呼び出しが交互に行われるのはなぜですか? また、ビューを正しいサイズで配置するように Android を説得するにはどうすればよいですか?

4

0 に答える 0