onMeasure()
は、カスタムビューは、親が提供するレイアウト制約依存するようにしたいどのように大きなアンドロイドを伝えるためにあなたの機会です。また、これらのレイアウト制約がある(場合には、あなたがwrap_content
状況よりmatch_parent
状況で異なる動作をします)何を学ぶためにカスタムビューの機会です。これらの制約は、メソッドに渡される値MeasureSpec
にパッケージ化されます。ここで、モード値の大まかな相関がある:
- を正確は
layout_width
又はlayout_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
でカスタムビューをレイアウト!
@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);
}
希望に役立ちます:あなたはView
ではなく、別の既存のウィジェットをオーバーライドしている場合
は一般的に、このようなもののように単純であったとしても、おそらく実装を提供することをお勧めします。
ちょっと@Devunwired素敵な説明私がこれまでに読んだ最高。あなたの説明は、私が持っていた多くの疑問に答えて、疑問を解決しましたが、それでもまだ残っています。私のカスタムビューが他のビューグループと一緒にViewGroup内にある場合ViewGroupはViewGroupがすべての子供をLayoutParams制約のための1つのプローブごとに、それぞれの子が制約に従って自己測定するように頼みますか? – pharaoh
はい、それは 'ViewGroup'の' measureChildren() 'メソッドがメジャー/レイアウトプロセス中に行うものです。 – Devunwired
ViewGroupサブクラスのonMeasureをオーバーライドすると、このコードは機能しません。あなたのサブビューは表示されず、すべて0x0のサイズになります。カスタムViewGroupのonMeasureをオーバーライドする必要がある場合は、widthMode、widthSize、heightModeおよびheightSizeを変更し、MeasureSpec.makeMeasureSpecを使用してmeasureSpecsにコンパイルし、結果の整数をsuper.onMeasureに渡します。 – Alexey