Android--カスタムレイアウトViewのonMesasure()メソッドの詳細
4505 ワード
Viewが画面に表示されるのはmeasure(計算)とlayout(レイアウト)
1.onMeasure()メソッドパラメータを詳しく解く
一般的には、自分自身に基づいてサイズを定義することができます.コントロールの親要素がコントロールを配置するとき、親要素はサブコントロールに「どのくらいの場所がほしいか」と質問し、2つのパラメータ、すなわちwidthMeasureSpaceとheightMeasureSpaceを入力します.この2つのコントロールで得られるコントロールと、この空間について説明するメタデータ.
onMeasure(int widthMeasureSpec,int heightMeasureSpec)では、2つのパラメータの役割:widthMeasureSpecとheightMeasureSpecの2つのintタイプのパラメータは、名前を見ると幅と高さに関係していることがわかるはずですが、それらは実際には幅と高さではなく、幅、高さとそれぞれの方向に対応するモードで合成された値です.ここで、intタイプの32ビットのバイナリビットでは、31-30の2桁はパターンを表す、0~29の30桁は幅と高さの実値を表す.このうちモードは全部で3種類あり、AndroidのViewクラスの1つの内部クラスに定義されている:View.MeasureSpec:①UNSPECIFIED:デフォルト値を表し、親コントロールはサブviewに制限を与えません.------バイナリ表示:00②EXACTLY:親コントロールがサブviewに具体的な値を与えることを示し、サブviewはこれらの値の大きさに設定する.------バイナリ表示:01③AT_MOST:親コントロールのサブviewの最大の特定の値を表し、サブviewはこの値の大きさを超えてはいけない.------バイナリ表示:10
より良い方法は、viewの高さと幅をsetMeasureDimension()メソッドに渡すことです.これにより、親コントロールにサブコントロールをどのくらい置く必要があるかを直接伝えることができます.
2、コードは以下の通りです.
2.1、方式一
2.2、方式二
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
1.onMeasure()メソッドパラメータを詳しく解く
一般的には、自分自身に基づいてサイズを定義することができます.コントロールの親要素がコントロールを配置するとき、親要素はサブコントロールに「どのくらいの場所がほしいか」と質問し、2つのパラメータ、すなわちwidthMeasureSpaceとheightMeasureSpaceを入力します.この2つのコントロールで得られるコントロールと、この空間について説明するメタデータ.
onMeasure(int widthMeasureSpec,int heightMeasureSpec)では、2つのパラメータの役割:widthMeasureSpecとheightMeasureSpecの2つのintタイプのパラメータは、名前を見ると幅と高さに関係していることがわかるはずですが、それらは実際には幅と高さではなく、幅、高さとそれぞれの方向に対応するモードで合成された値です.ここで、intタイプの32ビットのバイナリビットでは、31-30の2桁はパターンを表す、0~29の30桁は幅と高さの実値を表す.このうちモードは全部で3種類あり、AndroidのViewクラスの1つの内部クラスに定義されている:View.MeasureSpec:①UNSPECIFIED:デフォルト値を表し、親コントロールはサブviewに制限を与えません.------バイナリ表示:00②EXACTLY:親コントロールがサブviewに具体的な値を与えることを示し、サブviewはこれらの値の大きさに設定する.------バイナリ表示:01③AT_MOST:親コントロールのサブviewの最大の特定の値を表し、サブviewはこの値の大きさを超えてはいけない.------バイナリ表示:10
より良い方法は、viewの高さと幅をsetMeasureDimension()メソッドに渡すことです.これにより、親コントロールにサブコントロールをどのくらい置く必要があるかを直接伝えることができます.
2、コードは以下の通りです.
2.1、方式一
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//
int resultWidth = 0;
// mode
int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
// size
int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
/*
*
*/
if (modeWidth == MeasureSpec.EXACTLY) {
//
resultWidth = sizeWidth;
}
/*
*
*/
else {
//
resultWidth = mBitmap.getWidth();
/*
*
*/
if (modeWidth == MeasureSpec.AT_MOST) {
//
resultWidth = Math.min(resultWidth, sizeWidth);
}
}
int resultHeight = 0;
int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
if (modeHeight == MeasureSpec.EXACTLY) {
resultHeight = sizeHeight;
} else {
resultHeight = mBitmap.getHeight();
if (modeHeight == MeasureSpec.AT_MOST) {
resultHeight = Math.min(resultHeight, sizeHeight);
}
}
//
setMeasuredDimension(resultWidth, resultHeight);
}
2.2、方式二
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
}
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text
result = (int) mPaint.measureText(text) + getPaddingLeft() + getPaddingRight();
if (specMode == MeasureSpec.AT_MOST) {
// Respect AT_MOST value if that was what is called for by
// measureSpec
result = Math.min(result, specSize);
}
}
return result;
}
private int measureHeight(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
mAscent = (int) mPaint.ascent();
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text (beware: ascent is a negative number)
result = (int) (-mAscent + mPaint.descent()) + getPaddingTop() + getPaddingBottom();
if (specMode == MeasureSpec.AT_MOST) {
// Respect AT_MOST value if that was what is called for by
// measureSpec
result = Math.min(result, specSize);
}
}
return result;
}