Bindung ansehen Teil von Android Jetpack.

Die Ansichtsbindung erleichtert das Schreiben von Code, der mit Ansichten interagiert. Wenn die Ansichtsbindung in einem Modul aktiviert ist, wird für jede in diesem Modul vorhandene XML-Layoutdatei eine Bindungsklasse generiert. Eine Instanz einer Bindungsklasse enthält direkte Verweise auf alle Ansichten, die eine ID im entsprechenden Layout haben.

In den meisten Fällen ersetzt die Ansichtsbindung findViewById.

Einrichten

Die Ansichtsbindung wird für jedes Modul einzeln aktiviert. Wenn Sie die Ansichtsbindung in einem Modul aktivieren möchten, setzen Sie die Build-Option viewBinding in der Datei build.gradle auf Modulebene auf true, wie im folgenden Beispiel gezeigt:

Groovig

android {
    ...
    buildFeatures {
        viewBinding true
    }
}

Kotlin

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

Wenn Sie möchten, dass eine Layoutdatei beim Generieren von Bindungsklassen ignoriert wird, fügen Sie der Stammansicht dieser Layoutdatei das Attribut tools:viewBindingIgnore="true" hinzu:

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

Nutzung

Wenn Ansichtsbindung für ein Modul aktiviert ist, wird für jede im Modul enthaltene XML-Layoutdatei eine Bindungsklasse generiert. Jede Bindungsklasse enthält Verweise auf die Stammansicht und alle Ansichten, die eine ID haben. Der Name der Bindungsklasse wird generiert, indem der Name der XML-Datei in die Pascal-Case-Schreibweise konvertiert und am Ende das Wort „Binding“ hinzugefügt wird.

Betrachten Sie beispielsweise eine Layoutdatei namens result_profile.xml, die Folgendes enthält:

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

Die generierte Bindungsklasse heißt ResultProfileBinding. Diese Klasse hat zwei Felder: eine TextView mit dem Namen name und eine Button mit dem Namen button. Der ImageView im Layout hat keine ID, daher gibt es keinen Verweis darauf in der Bindungsklasse.

Jede Bindungsklasse enthält auch eine getRoot()-Methode, die eine direkte Referenz für die Stammansicht der entsprechenden Layoutdatei bietet. In diesem Beispiel gibt die Methode getRoot() in der Klasse ResultProfileBinding die Stammansicht LinearLayout zurück.

In den folgenden Abschnitten wird die Verwendung von generierten Bindungsklassen in Aktivitäten und Fragmenten veranschaulicht.

Ansichtsbindung in Aktivitäten verwenden

Führen Sie die folgenden Schritte in der Methode onCreate() der Aktivität aus, um eine Instanz der Bindungsklasse zur Verwendung mit einer Aktivität einzurichten:

  1. Rufen Sie die statische Methode inflate() auf, die in der generierten Bindungsklasse enthalten ist. Dadurch wird eine Instanz der Bindungsklasse für die zu verwendende Aktivität erstellt.
  2. Wenn Sie einen Verweis auf die Stammansicht abrufen möchten, rufen Sie entweder die Methode getRoot() auf oder verwenden Sie die Kotlin-Attributsyntax.
  3. Übergeben Sie die Stammansicht an setContentView(), um sie zur aktiven Ansicht auf dem Bildschirm zu machen.

Diese Schritte werden im folgenden Beispiel dargestellt:

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);
}

Sie können jetzt die Instanz der Bindungsklasse verwenden, um auf beliebige der Ansichten zu verweisen:

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()
});

Ansichtsbindung in Fragmenten verwenden

Führen Sie die folgenden Schritte in der Methode onCreateView() des Fragments aus, um eine Instanz der Bindungsklasse zur Verwendung mit einem Fragment einzurichten:

  1. Rufen Sie die statische Methode inflate() auf, die in der generierten Bindungsklasse enthalten ist. Dadurch wird eine Instanz der Bindungsklasse für das zu verwendende Fragment erstellt.
  2. Wenn Sie einen Verweis auf die Stammansicht abrufen möchten, rufen Sie entweder die Methode getRoot() auf oder verwenden Sie die Kotlin-Attributsyntax.
  3. Geben Sie die Stammansicht der Methode onCreateView() zurück, um sie zur aktiven Ansicht auf dem Bildschirm zu machen.

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;
}

Sie können jetzt die Instanz der Bindungsklasse verwenden, um auf beliebige der Ansichten zu verweisen:

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()
});

Hinweise für verschiedene Konfigurationen bereitstellen

Wenn Sie Ansichten für mehrere Konfigurationen deklarieren, kann es manchmal sinnvoll sein, je nach Layout einen anderen Ansichtstyp zu verwenden. Das folgende Code-Snippet zeigt ein Beispiel dafür:

# in res/layout/example.xml

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

# in res/layout-land/example.xml

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

In diesem Fall ist es wahrscheinlich, dass die generierte Klasse ein Feld userBio vom Typ TextView freigibt, da TextView die gemeinsame Basisklasse ist. Aufgrund technischer Einschränkungen kann der Generator für den Ansichtsbindungscode dies nicht ermitteln und generiert stattdessen ein View-Feld. Dazu muss das Feld später mit binding.userBio as TextView umgewandelt werden.

Zur Umgehung dieser Einschränkung unterstützt die Ansichtsbindung ein tools:viewBindingType-Attribut, mit dem Sie dem Compiler mitteilen können, welcher Typ im generierten Code verwendet werden soll. Im vorherigen Beispiel können Sie dieses Attribut verwenden, damit der Compiler das Feld als TextView generiert:

# 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" />

Angenommen, Sie haben zwei Layouts mit einem BottomNavigationView und ein anderes mit NavigationRailView. Beide Klassen erweitern NavigationBarView, das die meisten Implementierungsdetails enthält. Wenn Ihr Code nicht genau wissen muss, welche Unterklasse im aktuellen Layout vorhanden ist, können Sie tools:viewBindingType verwenden, um den generierten Typ in beiden Layouts auf NavigationBarView zu setzen:

# 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" />

Die Ansichtsbindung kann den Wert dieses Attributs beim Generieren von Code nicht validieren. Damit Kompilierungszeit- und Laufzeitfehler vermieden werden, muss der Wert die folgenden Bedingungen erfüllen:

  • Der Wert muss eine Klasse sein, die von android.view.View übernimmt.
  • Der Wert muss eine übergeordnete Klasse des Tags sein, in dem er platziert wird. Die folgenden Werte funktionieren beispielsweise nicht:

      <TextView tools:viewBindingType="ImageView" /> <!-- ImageView is not related to TextView. -->
      <TextView tools:viewBindingType="Button" /> <!-- Button is not a superclass of TextView. -->
    
  • Der endgültige Typ muss konsistent über alle Konfigurationen hinweg aufgelöst werden.

Unterschiede zu findViewById

Die Ansichtsbindung bietet wichtige Vorteile gegenüber der Verwendung von findViewById:

  • Null-Sicherheit:Da durch die Ansichtsbindung direkte Verweise auf Ansichten erstellt werden, besteht kein Risiko einer Nullzeigerausnahme aufgrund einer ungültigen Ansichts-ID. Wenn eine Ansicht nur in einigen Konfigurationen eines Layouts vorhanden ist, wird außerdem das Feld mit dem Verweis in der Bindungsklasse mit @Nullable gekennzeichnet.
  • Typensicherheit: Die Typen der Felder in den einzelnen Bindungsklassen entsprechen den Ansichten, auf die sie in der XML-Datei verweisen. Es besteht also kein Risiko für eine Klassenausnahme.

Diese Unterschiede führen dazu, dass Inkompatibilitäten zwischen Ihrem Layout und Ihrem Code dazu führen, dass Ihr Build bei der Kompilierung und nicht während der Laufzeit fehlschlägt.

Vergleich mit Datenbindung

Sowohl Ansichtsbindung als auch Datenbindung generieren Bindungsklassen, mit denen Sie Ansichten direkt referenzieren können. Die Ansichtsbindung ist jedoch für einfachere Anwendungsfälle vorgesehen und bietet gegenüber der Datenbindung folgende Vorteile:

  • Schnellere Kompilierung: Für die Ansichtsbindung ist keine Annotationsverarbeitung erforderlich, sodass die Kompilierungszeiten kürzer sind.
  • Nutzerfreundlichkeit:Für die Ansichtsbindung sind keine speziell getaggten XML-Layoutdateien erforderlich. Sie lässt sich daher schneller in Ihren Apps verwenden. Sobald Sie die Ansichtsbindung in einem Modul aktivieren, wird sie automatisch auf alle Layouts dieses Moduls angewendet.

Andererseits gelten für die Ansichtsbindung die folgenden Einschränkungen im Vergleich zur Datenbindung:

Aufgrund dieser Überlegungen ist es in einigen Fällen am besten, in einem Projekt sowohl die Ansichtsbindung als auch die Datenbindung zu verwenden. Sie können die Datenbindung in Layouts verwenden, die erweiterte Funktionen erfordern, und die Ansichtsbindung in Layouts, in denen das nicht der Fall ist.

Weitere Informationen

Weitere Informationen zur Ansichtsbindung finden Sie in den folgenden Ressourcen:

Produktproben

Blogs

Videos