カスタムビューは、View または View のサブクラスを継承し、新しいクラスで対応する処理ロジック(関連するメソッドのオーバーライド)を実装することによって、自分が望む効果を達成するものです。
カテゴリ#
- カスタム ViewGroup:カスタム ViewGroup は、既存のコンポーネントを使用して特定のレイアウト方法で新しいコンポーネントを構成するために使用されます。主に ViewGroup またはさまざまなレイアウトを継承し、子 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 を測定し、測定結果を一時的に保存します。ViewGroup は、子 View の実際のサイズに基づいて自身の期待サイズを計算し、setMeasuredDimension () メソッドを使用して親 View(ViewGroup の親 View)に自身の期待サイズを通知します。
- メソッド内で setMeasuredDimension () メソッドを呼び出して、親 View に自身の期待サイズを通知します。
onMeasure () は、View の期待サイズを計算するメソッドです:
- 親 View の View のサイズ要件と実際のビジネス要件に基づいて、View の期待サイズを計算します:
- widthMeasureSpec を解析します。
- heightMeasureSpec を解析します。
- 「実際のビジネス要件に基づいて View のサイズを計算」を「親 View の View のサイズ要件」に基づいて修正し、View の期待サイズを計算します(resolveSize () メソッドを呼び出して計算します)。
- 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 の特定の状態を監視するためのインターフェースを提供します。