カスタムビューは、View または View のサブクラスを継承し、新しいクラスで対応する処理ロジック(関連するメソッドのオーバーライド)を実装することによって、自分が望む効果を達成するものです。
カテゴリ#
- カスタム ViewGroup:カスタム ViewGroup は、既存のコンポーネントを使用して特定のレイアウト方法で新しいコンポーネントを作成するために使用されます。主に ViewGroup またはさまざまなレイアウトを継承し、子 View を含みます。
- カスタム View:既存の View がない場合や自分で実装する必要がある場合には、カスタム View を使用します。通常、View、SurfaceView、または他の View を継承し、子 View を含みません。
コンストラクタ#
システムの View を継承するか、直接 View を継承する場合、コンストラクタをオーバーライドする必要があります。コンストラクタは複数ありますが、少なくとも 1 つをオーバーライドする必要があります。
public class TestView extends View {
/**
* Javaコードでnewするときに使用されます
* @param context
*/
public TestView(Context context) {
super(context);
}
/**
* XMLレイアウトファイルで使用されると自動的に呼び出されます
* @param context
*/
public TestView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
/**
* 自動的に呼び出されません。デフォルトのスタイルがある場合は、2番目のコンストラクタで呼び出されます
* @param context
* @param attrs
* @param defStyleAttr
*/
public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* APIバージョン>21の場合にのみ使用されます
* 自動的に呼び出されません。デフォルトのスタイルがある場合は、2番目のコンストラクタで呼び出されます
* @param context
* @param attrs
* @param defStyleAttr
* @param defStyleRes
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
}
描画プロセス#
- 測定
- レイアウト
- 描画
- インターフェースの提供
測定フェーズ#
- View の親 View は、View の measure () メソッドを呼び出して、親 View から View へのサイズ要件を渡します。
- View の measure () メソッドは、いくつかの前処理と最適化を行います。
- onMeasure () メソッドを呼び出し、ビジネス要件に応じたロジックを実装します。カスタム ViewGroup の onMeasure () メソッドでは、ViewGroup は子 View の measure () メソッドを再帰的に呼び出し、measure () を使用して ViewGroup の子 View のサイズ要件を計算し、計測結果を一時的に保存します。ViewGroup は、子 View の実際のサイズに基づいて自身の期待サイズを計算し、setMeasuredDimension () メソッドを使用して親 View(ViewGroup の親 View)に自身の期待サイズを通知します。
- setMeasuredDimension () メソッドを使用して、親 View に自身の期待サイズを通知します。
onMeasure () メソッドは、View の期待サイズを計算する方法です:
- 親 View の View のサイズ要件と実際のビジネス要件に基づいて、View の期待サイズを計算します:
- widthMeasureSpec を解析します。
- heightMeasureSpec を解析します。
- 「実際のビジネス要件に基づいて View のサイズを計算し、親 View の View のサイズ要件に基づいて修正する」ために、resolveSize () メソッドを使用して View の期待サイズを計算します。
- setMeasuredDimension () を使用して、View の期待サイズを保存します(実際には、setMeasuredDimension () を使用して親 View に自身の期待サイズを通知します)。
onMeasure() :
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthsize MeasureSpec.getSize(widthMeasureSpec); //幅の正確な値を取得します
int widthmode MeasureSpec.getMode(widthMeasureSpec); //幅の測定モードを取得します
int heightsize MeasureSpec.getSize(heightMeasureSpec); //高さの正確な値を取得します
int heightmode MeasureSpec.getMode(heightMeasureSpec); //高さの測定モードを取得します
}
widthMeasureSpec と heightMeasureSpec は、幅と高さではなく、幅、高さ、およびそれぞれの方向の対応する測定モードから合成される int 型のパラメータです。
レイアウトフェーズ#
- 親 View は、View の Layout () メソッドを呼び出して、View の実際のサイズを View に渡します。
- View は Layout () メソッド内で setFrame () メソッドを呼び出して保存します。
- setFrame () メソッドでは、onSizeChanged () メソッドを呼び出して、View のサイズが変更されたことを開発者に通知します。
- View の Layout () メソッドは View の onLayout () メソッドを呼び出します。これは空の実装ですが、ViewGroup では、ここで子 View の Layout () メソッドを呼び出し、子 View の実際のサイズを渡して保存します。カスタム ViewGroup では、このメソッドをオーバーライドする必要があります。
描画フェーズ#
- draw () は、背景の描画メソッド、テーマの描画メソッド、前景の描画メソッド、および子 View の描画メソッドを呼び出す総合的なディスパッチメソッドです。
- onDraw () は、View の本体コンテンツを描画するメソッドです。
- dispatchDraw () は、子 View の描画メソッドであり、カスタム ViewGroup では、ViewGroup.drawChild () メソッドを呼び出します。このメソッドは、各子 View の View.draw () を呼び出します。
- drawBackground () は、背景を描画するメソッドであり、オーバーライドできません。背景を設定するには、xml レイアウトファイルまたは setBackground () メソッドを使用する必要があります。
- onDrawForegound () は、View の前景を描画するメソッドであり、主体コンテンツの上に描画するものを実装する場合は、このメソッドで行います。
インターフェースの提供#
View を制御したり、View の特定の状態を監視するためのインターフェースを提供します。