カスタムビュー コンポーネントを作成する

Compose を試す
Jetpack Compose は、Android に推奨される UI ツールキットです。Compose でレイアウトを操作する方法を学習します。
<ph type="x-smartling-placeholder"></ph> Compose のカスタム レイアウト →

Android では、高度でパワフルなコンポーネント化されたモデルを使用して UI を構築できます。 基本的なレイアウト クラスを ViewViewGroup。プラットフォームには ウィジェットと呼ばれる、さまざまなビルド済み View サブクラスと ViewGroup サブクラス (UI の作成に使用できます)

利用可能なウィジェットとしては、ButtonTextViewEditTextListViewCheckBoxRadioButtonGallerySpinner などがあり、特別な用途を持つ AutoCompleteTextViewImageSwitcherTextSwitcher などもあります。

使用可能なレイアウトには LinearLayout, FrameLayout, RelativeLayout, その他。その他の例については、 一般的なレイアウト

ビルド済みのウィジェットやレイアウトでニーズを満たせない場合は、独自のウィジェットを作成できます。 View サブクラス。既存のウィジェットや ウィジェットまたはレイアウトをサブクラス化して、そのメソッドをオーバーライドできます。

独自の View サブクラスを作成すると、外観と動作を細かく制御できます。 呼び出すことができます。カスタムビューで利用できるコントロールについては、以下をご覧ください。 いくつかの操作の例を紹介します。

  • 完全にカスタム レンダリングされる View タイプ(「ボリューム」など)を作成できます。 管理"2D グラフィックスを使ってレンダリングされた、アナログの電子制御装置によく似たつまみ。
  • View コンポーネントのグループを新しい 1 つのコンポーネントにまとめることができます。たとえば、次のようになります。 コンボボックス(ポップアップ リストと自由入力テキスト フィールドの組み合わせ)のようなもの、 デュアルペイン セレクタ コントロール(左側と右側のペインにリストが表示され、各ペインで再割り当て可能 そのリストに含まれるアイテム)を抽出できます。
  • EditText コンポーネントの画面上のレンダリング方法をオーバーライドできます。「 <ph type="x-smartling-placeholder"></ph> サンプルアプリの NotePad では、これを使って枠線付きのメモ帳を作成しています。
  • 他のイベント(キーの押下など)をキャプチャして、カスタムな方法で処理できます。 見てきました。

以降のセクションでは、カスタムビューを作成して、アプリケーションで使用する方法について説明します。対象 詳しくは、 View クラス。

基本的なアプローチ

ここでは、独自の View を作成する際に知っておくべきことの概要を説明します。 components:

  1. 既存の View クラスまたはサブクラスを独自のクラスで拡張します。
  2. スーパークラスの一部のメソッドをオーバーライドします。オーバーライドするスーパークラスのメソッドは、 on - 例: onDraw(), onMeasure(), および onKeyDown()。 これは次のイベントの on イベントと Activity または ListActivity で オーバーライドできます。
  3. 新しい拡張クラスを使用します。完了したら、代わりに新しい拡張機能クラスを使用できます。 基づいたビューです。
で確認できます。 <ph type="x-smartling-placeholder">

完全にカスタマイズされたコンポーネント

自由にカスタマイズできるグラフィカル コンポーネントを作成できます。 できます。古いアナログ ゲージのような視覚的な VU メーターや、一緒に歌を歌うテキスト表示が欲しい場合があります。 カラオケマシンに乗って歌うときに、単語に合わせて弾むボールが動きます。おすすめ どのような方法で組み合わせる場合でも、組み込みコンポーネントではできない処理です。

幸い、見た目と動作が自由なコンポーネントを作成できます。 画面のサイズ、利用可能な処理能力に応じて異なります。 デスクトップよりかなり低消費電力のデバイスで動作し、 あります。

完全にカスタマイズされたコンポーネントを作成するには、次の点を考慮してください。

  • 拡張できる最も汎用的なビューは View であるため、通常はまず拡張から始めます。 新しい super コンポーネントを作成します。
  • XML から属性とパラメータを取得できるコンストラクタを用意できます。また、 独自の属性やパラメータ(VU メーターの色や範囲など)を 針の幅と減衰量に応じて調整します
  • 通常は、独自のイベント リスナー、プロパティ アクセサ、修飾子を作成し、 コンポーネント クラスでより高度な動作を行うことをおすすめします。
  • onMeasure() のオーバーライドが必要になることはほぼ確実です。また、以下を行う必要があります。 コンポーネントになんらかの表示をさせる場合は、onDraw() をオーバーライドします。両方とも デフォルトの動作として、onDraw() は何も行わず、 onMeasure() では常に 100x100 のサイズが設定されますが、これはおそらく望ましくありません。
  • 必要に応じて、他の on メソッドをオーバーライドすることもできます。

onDraw() と onMeasure() を拡張する

onDraw() メソッドは、 Canvas を割り当て 2D グラフィック、その他の標準またはカスタム コンポーネント、スタイル付きテキスト、 思いつく限りあらゆるものになります。

<ph type="x-smartling-placeholder">

onMeasure() の場合はもう少し複雑です。onMeasure() は重要な要素です コンポーネントとそのコンテナ間のレンダリングのコントラクトについて 学びますonMeasure() は次の値にしてください オーバーライドすることで、含まれている部品の測定値を効率的かつ正確に報告できます。これは、 親からの制限要件により少し複雑になります。制限の要件は onMeasure() メソッドを使用し、 移動後に測定された幅と高さを持つ setMeasuredDimension() メソッド 計算します。オーバーライドされた onMeasure() メソッドからこのメソッドを呼び出さないと、 測定時に例外が発生します。

大まかに言うと、onMeasure() の実装は次のようになります。

  • オーバーライドされた onMeasure() メソッドが、幅と高さを指定して呼び出される 仕様。これらの仕様は、幅と高さの制限に対する要件として扱われます。 測定しますwidthMeasureSpec および heightMeasureSpec パラメータはどちらもディメンションを表す整数コードです。この種類のリソースへの完全リファレンス これらの仕様で指定できる制限については、 View.onMeasure(int, int) このリファレンス ドキュメントでは、測定操作全体についても説明します。
  • コンポーネントの onMeasure() メソッドで、測定の幅と高さが計算されます。 コンポーネントのレンダリングに必要な パラメータを設定します仕様の範囲内に収まるようにする必要があります。 上限を超えることがありますその場合、保護者は以下のような操作を行うことができます。 クリッピング、スクロール、例外のスロー、onMeasure() への再試行 異なる可能性があります
  • 幅と高さを計算したら、 計算された値を含む setMeasuredDimension(int width, int height) メソッド 測定します。これを行わないと、例外が発生します。

フレームワークがビューに対して呼び出すその他の標準メソッドの概要は次のとおりです。

カテゴリ メソッド 説明
作成 コンストラクタ コードからビューが作成されるときに呼び出される形式のコンストラクタがあります。 ビューがレイアウト ファイルからインフレートされたときに呼び出されるフォームがあります。2 つ目のフォーム レイアウト ファイルで定義されている属性を解析して適用します。
onFinishInflate() ビューとそのすべての子が XML からインフレートされた後に呼び出されます。
レイアウト onMeasure(int, int) このビューとそのすべての子のサイズ要件を指定するために呼び出されます。
onLayout(boolean, int, int, int, int) このビューがそのすべての子にサイズと位置を割り当てる必要がある場合に呼び出されます。
onSizeChanged(int, int, int, int) このビューのサイズが変更されたときに呼び出されます。
図形描画 onDraw(Canvas) ビューがそのコンテンツをレンダリングする必要がある場合に呼び出されます。
イベント処理 onKeyDown(int, KeyEvent) キーダウン イベントの発生時に呼び出されます。
onKeyUp(int, KeyEvent) キーアップ イベントの発生時に呼び出されます。
onTrackballEvent(MotionEvent) トラックボールのモーション イベントが発生したときに呼び出されます。
onTouchEvent(MotionEvent) タッチスクリーンのモーション イベントが発生したときに呼び出されます。
フォーカス onFocusChanged(boolean, int, Rect) ビューがフォーカスを取得したとき、またはフォーカスを喪失したときに呼び出されます。
onWindowFocusChanged(boolean) ビューを含むウィンドウがフォーカスを取得または失ったときに呼び出されます。
アタッチ onAttachedToWindow() ビューがウィンドウにアタッチされたときに呼び出されます。
onDetachedFromWindow() ビューがウィンドウからデタッチされたときに呼び出されます。
onWindowVisibilityChanged(int) ビューを含むウィンドウの表示状態が変更されたときに呼び出されます。

複合コントロール

完全にカスタマイズしたコンポーネントを作成するのではなく、 既存のコントロールのグループで構成される再利用可能なコンポーネントを 複合制御が最適かもしれません。まとめると、さらに多くの 単一のものとして扱えるアイテムの論理グループへのアトミック コントロールやビュー。 たとえば、1 行の EditText フィールドを組み合わせたコンボボックスを作成できます。 ポップアップ リストが添付された隣のボタンです。ユーザーがボタンをタップして EditText フィールドに値が設定されますが、値を入力することもできます。 必要に応じて EditText に直接挿入します。

Android では、これを簡単に行うことができるビューが他に Spinner と 2 つあります。 AutoCompleteTextView。いずれにせよ、コンボ ボックスのこのコンセプトは良い例です。

複合コンポーネントを作成する手順は次のとおりです。

  • Activity と同様に、宣言型(XML ベース)のアプローチ を使用して、含まれているコンポーネントを作成するか、コードからプログラムでコンポーネントをネストします。「 通常の開始点はなんらかの Layout であるため、 Layout。コンボボックスの場合は、LinearLayout と 追加できます他のレイアウトを内部にネストして、複合コンポーネントを 任意の複雑で構造化されている場合があります。
  • 新しいクラスのコンストラクタで、スーパークラスが想定しているパラメータを受け取り、 まずスーパークラス コンストラクタに渡します。その後、他のビューを設定して、 新しいコンポーネントに追加します。ここで、EditText フィールドと ポップアップ リストです。構成する XML に独自の属性とパラメータを導入し、 pull して使用できます。
  • 必要に応じて、含まれるビューが生成する可能性のあるイベントのリスナーを作成します。たとえば リストアイテムのクリック リスナーのリスナー メソッドで、 リストが選択されている場合は EditText
  • 必要に応じて、アクセサと修飾子を使用して独自のプロパティを作成します。たとえば、 コンポーネントで最初に EditText 値を設定し、次の場合にその内容をクエリします。 必要ありません。
  • 必要に応じて、onDraw()onMeasure() をオーバーライドします。これは通常、 Layout を拡張する(レイアウトにデフォルトの動作があり、問題なく動作する可能性があるため)。
  • 必要に応じて、他の on メソッド(onKeyDown() など)をオーバーライドします。たとえば、 特定のキーがタップされたときにコンボボックスのポップアップ リストからデフォルト値を設定できます。

Layout をカスタム コントロールのベースとして使用すると、 例:

  • アクティビティ画面と同様に、宣言型 XML ファイルを使用してレイアウトを指定できます。 プログラムでビューを作成して、コードからレイアウト内にネストすることもできます。
  • onDraw() メソッドと onMeasure() メソッド、その他のほとんどのメソッド on メソッドは適切な動作をするため、オーバーライドする必要はありません。
  • 任意の複雑な複合ビューをすばやく作成して、あたかも 2 つの 単一コンポーネントです

既存のビュータイプを変更する

必要とするものと似たコンポーネントがある場合は、そのコンポーネントを拡張してオーバーライドする 動作を変更できます。あらゆる作業をこなせるため、 View 階層のより特殊なクラスから始めることで、 やりたいことを無料で実行できます。

たとえば、 メモ帳 サンプルアプリでは、Android プラットフォームの使い方をさまざまな側面から紹介しています。そのうちの 1 つは、 EditText ビューをクリックして、枠線付きのメモ帳を作成します。これは完璧な例ではなく 変わる可能性がありますが、あくまで原則です。

まだの場合は、NotePad サンプルを Android Studio にインポートするか、 できます。特に、LinedEditText の定義をご覧ください。 の NoteEditor.java 表示されます。

このファイルの主なポイントは以下のとおりです。

  1. 定義

    クラスは、次の行で定義されています。
    public static class LinedEditText extends EditText

    LinedEditTextNoteEditor 内の内部クラスとして定義されている アクティビティですが、NoteEditor.LinedEditText としてアクセスできるよう公開されています NoteEditor クラスの外部から使用できます。

    また、LinedEditTextstatic です。つまり、 いわゆる「合成メソッド」と呼ばれるものです。親クラスのデータにアクセスできます。つまり、 は、NoteEditor との関連性が強いものではなく、別のクラスとして動作します。 これにより、内部クラスが外部クラスから状態にアクセスする必要がない場合に、よりクリーンな方法で作成できます。 使用できます。生成されるクラスを小さく保ち、他のクラスから簡単に使用できるようにします。 。

    LinedEditText は、カスタマイズするビューである EditText を拡張します。 できます。完了すると、新しいクラスが通常の EditText に置き換えることができます。 表示されます。

  2. クラスの初期化

    通常どおり、先にスーパークラスを呼び出します。これはデフォルトのコンストラクタではありませんが、 作成します。EditText は、作成時にこれらのパラメータを使用して作成されます。 XML レイアウト ファイルからインフレートできます。したがって、コンストラクタはそれらを取得して、 スーパークラス コンストラクタも使用できます。

  3. オーバーライドされたメソッド

    この例では onDraw() メソッドのみをオーバーライドしていますが、 独自のカスタムコンポーネントを作成するときに 使用できます

    このサンプルでは、onDraw() メソッドをオーバーライドすることで、青い線を描画できます。 EditText ビュー キャンバスです。キャンバスは、オーバーライドされた onDraw() メソッドを使用します。super.onDraw() メソッドは、 メソッドを終了します。スーパークラス メソッドを呼び出す必要があります。この場合は、コマンドの後の最後で呼び出します。 挿入したい線を描画します

  4. カスタム コンポーネント

    これでカスタム コンポーネントが用意できました。では、どのように使用すればよいでしょうか。メモ帳の例では、 カスタム コンポーネントは宣言型レイアウトから直接使用されるため、 note_editor.xmlres/layout フォルダ:

    <view xmlns:android="http://schemas.android.com/apk/res/android"
        class="com.example.android.notepad.NoteEditor$LinedEditText"
        android:id="@+id/note"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/transparent"
        android:padding="5dp"
        android:scrollbars="vertical"
        android:fadingEdge="vertical"
        android:gravity="top"
        android:textSize="22sp"
        android:capitalize="sentences"
    />
    

    カスタム コンポーネントは XML で汎用ビューとして作成され、 使用できます。定義した内部クラスは、 NoteEditor$LinedEditText 表記(内部を参照する標準的な方法です) Java プログラミング言語で記述できます。

    カスタムビュー コンポーネントが内部クラスとして定義されていない場合は、ビューを宣言して XML 要素名を追加して、class 属性を除外します。次に例を示します。

    <com.example.android.notepad.LinedEditText
      id="@+id/note"
      ... />
    

    この場合、LinedEditText クラスは独立したクラスファイルになります。Google クラスが NoteEditor クラスにネストされている場合、この手法は機能しません。

    定義内の他の属性とパラメータは、カスタム EditText コンストラクタに渡されるため、 EditText ビューで使用するものと同じパラメータです。必要に応じて 独自のパラメータも使用できます。

カスタム コンポーネントの作成は、必要なだけ複雑です。

より高度なコンポーネントでは、さらに多くの on メソッドをオーバーライドして、 独自のヘルパー メソッドを作成し、そのプロパティと動作を大幅にカスタマイズします。上限は コンポーネントにさせたいこと という観点で考える必要があります