ビュー バインディング Android Jetpack の一部。

ビュー バインディング: やり取りを行うコードを簡単に記述できる 説明します。モジュールでビュー バインディングが有効になると、バインディングが生成される class を、そのモジュールに存在する各 XML レイアウト ファイルに対して呼び出します。バインディングのインスタンス クラスに ID を持つすべてのビューへの直接参照が含まれ、 対応するレイアウトです。

ほとんどの場合、ビュー バインディングは findViewById の後継となります。

設定

ビュー バインディングはモジュール単位で有効になります。API でビュー バインディングを有効にするには、 モジュール レベルで、viewBinding ビルド オプションを true に設定します。 build.gradle ファイルに追加します。

Groovy

android {
    ...
    buildFeatures {
        viewBinding true
    }
}

Kotlin

android {
    ...
    buildFeatures {
        viewBinding = true
    }
}

バインディング クラスの生成時にレイアウト ファイルを無視するには、 そのレイアウトのルートビューに tools:viewBindingIgnore="true" 属性を追加します。 ファイル:

<LinearLayout
        ...
        tools:viewBindingIgnore="true" >
    ...
</LinearLayout>

使用方法

モジュールに対してビュー バインディングが有効になっている場合、モジュールごとにバインディング クラスが生成される モジュールに含まれる XML レイアウト ファイル。各バインディング クラスには参照が含まれる ID を持つすべてのビューに適用されます。バインディング クラスの名前は XML ファイルの名前をパスカルケースに変換し、 単語「Binding」説明します。

たとえば、次の内容を含む result_profile.xml というレイアウト ファイルについて考えてみましょう。 次のとおりです。

<LinearLayout ... >
    <TextView android:id="@+id/name" />
    <ImageView android:cropToPadding="true" />
    <Button android:id="@+id/button"
        android:background="@drawable/rounded_button" />
</LinearLayout>

生成されるバインディング クラスは、ResultProfileBinding という名前になります。このクラスには 2 つのフィールドがあります。name という TextViewbutton という Button です。「 レイアウト内の ImageView に ID がないため、レイアウト内に参照がありません。 あります。

すべてのバインディング クラスには getRoot() メソッドもあり、 対応するレイアウト ファイルのルートビューへの参照です。この例では ResultProfileBinding クラスの getRoot() メソッドは LinearLayout ルートビュー。

以降のセクションでは、Terraform で生成されたバインディング クラスの使用方法を説明します。 アクティビティとフラグメントです

アクティビティでビュー バインディングを使用する

アクティビティで使用するためにバインディング クラスのインスタンスをセットアップするには、次の手順を行います。 アクティビティの onCreate() メソッド:

  1. 生成されたバインディング クラスに含まれる静的 inflate() メソッドを呼び出します。 これにより、アクティビティで使用するバインディング クラスのインスタンスが作成されます。
  2. getRoot() メソッドを呼び出すか、ルートビューへの参照を取得します。 Kotlin プロパティを使用 構文をご覧ください。
  3. ルートビューを setContentView() 画面上のアクティブビューにします

手順を次の例に示します。

Kotlin

private lateinit var binding: ResultProfileBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ResultProfileBinding.inflate(layoutInflater)
    val view = binding.root
    setContentView(view)
}

Java

private ResultProfileBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ResultProfileBinding.inflate(getLayoutInflater());
    View view = binding.getRoot();
    setContentView(view);
}

これで、バインディング クラスのインスタンスを使用して任意のビューを参照できるようになりました。

Kotlin

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

Java

binding.name.setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
    viewModel.userClicked()
});

フラグメントでビュー バインディングを使用する

フラグメントで使用するバインディング クラスのインスタンスをセットアップするには、次のようにします。 フラグメントの onCreateView() メソッド:

  1. 生成されたバインディング クラスに含まれる静的 inflate() メソッドを呼び出します。 これにより、フラグメントが使用するバインディング クラスのインスタンスが作成されます。
  2. getRoot() メソッドを呼び出すか、ルートビューへの参照を取得します。 Kotlin プロパティを使用 構文をご覧ください。
  3. onCreateView() メソッドからルートビューを返して、 アクティブビューです
で確認できます。

Kotlin

private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    _binding = ResultProfileBinding.inflate(inflater, container, false)
    val view = binding.root
    return view
}

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}

Java

private ResultProfileBinding binding;

@Override
public View onCreateView (LayoutInflater inflater,
                          ViewGroup container,
                          Bundle savedInstanceState) {
    binding = ResultProfileBinding.inflate(inflater, container, false);
    View view = binding.getRoot();
    return view;
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    binding = null;
}

これで、バインディング クラスのインスタンスを使用して任意のビューを参照できるようになりました。

Kotlin

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

Java

binding.name.setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
    viewModel.userClicked()
});

さまざまな構成のヒントを提供する

複数の構成でビューを宣言すると、 特定のレイアウトに応じて異なるビュータイプを使用するのがよいでしょう。 次のコード スニペットは、この例を示しています。

# in res/layout/example.xml

<TextView android:id="@+id/user_bio" />

# in res/layout-land/example.xml

<EditText android:id="@+id/user_bio" />

この場合、生成されるクラスがフィールド userBio を公開することが想定されます。 TextView 型。TextView が共通の基本クラスであるため。理由 ビュー バインディングのコード生成ツールは、 代わりに View フィールドを生成します。これを行うには、後で binding.userBio as TextView

この制限を回避するために、ビュー バインディングでは tools:viewBindingType をサポートしています。 属性を使用して、生成されたコードで使用する型をコンパイラに指示できます。 上記の例では、この属性を使用して、コンパイラが フィールドを TextView として生成します。

# in res/layout/example.xml (unchanged)

<TextView android:id="@+id/user_bio" />

# in res/layout-land/example.xml

<EditText android:id="@+id/user_bio" tools:viewBindingType="TextView" />

別の例では、2 つのレイアウトがあり、そのうちの 1 つに BottomNavigationView と、NavigationRailView を含むもう 1 つ。両方 クラスは、ほとんどの実装を含む NavigationBarView を拡張します。 表示されます。どのサブクラスが存在するかをコードで正確に認識する必要がない場合は、 tools:viewBindingType を使用すると、生成された要素を 両方のレイアウトで NavigationBarView に入力すると、次のようになります。

# in res/layout/navigation_example.xml

<BottomNavigationView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />

# in res/layout-w720/navigation_example.xml

<NavigationRailView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />

コードの生成時に、ビュー バインディングではこの属性の値を検証できません。宛先 コンパイル時とランタイム エラーを回避するため、値は次の条件を満たす必要があります。 条件:

  • 値には、android.view.View から継承したクラスを指定する必要があります。
  • 値は、配置するタグのスーパークラスにする必要があります。たとえば、 次の値は機能しません。

      <TextView tools:viewBindingType="ImageView" /> <!-- ImageView is not related to TextView. -->
      <TextView tools:viewBindingType="Button" /> <!-- Button is not a superclass of TextView. -->
    
  • 最終的な型は、すべての構成で一貫して解決する必要があります。

findViewById との違い

ビュー バインディングには、findViewById を使用するよりも大きなメリットがあります。

  • null の安全性: ビュー バインディングではビューへの直接参照が作成されるため、 ビュー ID が無効なために null ポインタ例外が発生するリスクはありません。 また、ビューが一部の構成にのみ存在する場合、 バインディング クラス内にその参照を含むフィールドが @Nullable で。
  • 型安全性: 各バインディング クラスのフィールドには、 XML ファイルで参照できます。つまり クラスの外部 IP アドレスに キャスト例外が発生します。

こうした違いは、レイアウトとコードの間に互換性がないことを意味します。 その結果、実行時ではなくコンパイル時にビルドが失敗します。

データ バインディングとの比較

ビュー バインディングとデータ バインディングはどちらも ビューを直接参照するために使用できるバインディング クラスがあります。ただし、 バインディングは、より単純なユースケースを処理することが目的であり、次の機能を提供します。 データ バインディングより優れている点:

  • コンパイルの高速化: ビュー バインディングにアノテーション処理が必要ないため、 コンパイル時間が短縮されます
  • 使いやすさ: ビュー バインディングで、特別にタグ付けした XML レイアウトを必要としない アプリに迅速に導入できますGoogle Cloud コンソールでビュー バインディングを有効にすると、 そのモジュールのすべてのレイアウトに自動的に適用されます。

一方、ビュー バインディングには、データと比較して次のような制限があります。 binding:

  • ビュー バインディングはレイアウト変数やレイアウトをサポートしない ないため、 XML レイアウト ファイルから直接、動的 UI コンテンツを宣言できます。
  • ビュー バインディングは双方向データをサポートしていない バインディングをご覧ください。

これらの考慮事項により、場合によっては両方のビューを使用することをおすすめします。 バインディングとデータバインディングの ベストプラクティスをご覧くださいデータ バインディングは、 高度な機能が必要で、必要のないレイアウトでビュー バインディングを使用する。

参考情報

ビュー バインディングの詳細については、次の参考情報をご覧ください。

サンプル

ブログ

動画