onMeasure()
カスタムビューが親によって提供されるレイアウト制約に依存する大きさをAndroidに伝える機会です。match_parent
また、これらのレイアウト制約が何であるかを学習するカスタムビューの機会でもあります(状況と状況で異なる動作をしたい場合wrap_content
)。これらの制約はMeasureSpec
、メソッドに渡される値にパッケージ化されます。モード値の大まかな相関関係は次のとおりです。
- EXACTLYは、
layout_width
orlayout_height
値が特定の値に設定されたことを意味します。おそらく、ビューをこのサイズにする必要があります。これは、使用時にトリガーmatch_parent
されて、サイズを親ビューに正確に設定することもできます(これはフレームワークのレイアウトに依存します)。
- AT_MOSTは通常、
layout_width
またはlayout_height
値が最大サイズが必要な場所に設定されてmatch_parent
いることを意味しwrap_content
(これはフレームワークのレイアウトに依存します)、親ディメンションのサイズが値です。このサイズより大きくすることはできません。
- UNSPECIFIEDは通常、
layout_width
またはlayout_height
値がwrap_content
制限なしで設定されたことを意味します。あなたはあなたが望むどんなサイズでもありえます。一部のレイアウトでは、このコールバックを使用して目的のサイズを把握してから、2番目のメジャーリクエストで実際に再度渡すスペックを決定します。
に存在するコントラクトonMeasure()
は、ビューを希望するサイズで最後に呼び出す必要がありますsetMeasuredDimension()
。このメソッドは、にあるデフォルトの実装を含むすべてのフレームワーク実装によって呼び出されます。そのため、ユースケースに適合する場合は、代わりView
に呼び出すのが安全です。super
確かに、フレームワークはデフォルトの実装を適用するため、このメソッドをオーバーライドする必要はないかもしれませんが、そうでない場合、およびレイアウトする場合、ビュースペースがコンテンツよりも小さい場合にクリッピングが発生する可能性があります。wrap_content
両方向のカスタムビューでは、フレームワークがビューの大きさを認識していないため、ビューがまったく表示されない場合があります。
一般に、オーバーライドView
していて、別の既存のウィジェットではない場合は、次のような単純なものであっても、実装を提供することをお勧めします。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int desiredWidth = 100;
int desiredHeight = 100;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
//Measure Width
if (widthMode == MeasureSpec.EXACTLY) {
//Must be this size
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
width = Math.min(desiredWidth, widthSize);
} else {
//Be whatever you want
width = desiredWidth;
}
//Measure Height
if (heightMode == MeasureSpec.EXACTLY) {
//Must be this size
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
height = Math.min(desiredHeight, heightSize);
} else {
//Be whatever you want
height = desiredHeight;
}
//MUST CALL THIS
setMeasuredDimension(width, height);
}
お役に立てば幸いです。