ビュー バインディング 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 コンテンツを宣言できます。
  • ビュー バインディングは双方向データをサポートしていない バインディングをご覧ください。

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

参考情報

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

サンプル

ブログ

動画