Erste Schritte mit Jetpack: DataBinding

Inhaltsverzeichnis

1. Einführung in DataBinding

SetupDataBinding

Datenbindungsausdruck

Zwei-Wege-Bindung

2. Beispiele

Beispiel 1: DataBinding implementiert Textbindung und Klickereignisse

 Hauptaktivität :

CountStart:

Essen: 

 OnClickListener:

 Aktivität_main:

 build.gradle:

Operationsergebnis:

Beispiel 2: Bindung der sekundären Schnittstelle

  Aktivität_main:

sub_main: 

Beispiel 3. Beispiel für bidirektionale Bindung

 Hauptaktivität:

 ViewModel:

 Aktivität_main:

Beispiel 4: Verwenden Sie die Annotation @bindingAdapter, um Bilder zu laden

Hauptaktivität : 

ImageBindingAdapter: 

Aktivität_main: 

 Vorsichtsmaßnahmen:

3. Zusammenfassung

1. Einführung in DataBinding

        DataBinding ist eine Bibliothek für die präzise und effiziente Datenbindung in Android-Anwendungen. Es ermöglicht Entwicklern, UI-Komponenten deklarativ an Datenquellen zu binden, Daten auf der Schnittstelle automatisch zu aktualisieren und den UI-bezogenen Code-Schreibprozess zu vereinfachen.

SetupDataBinding

Um die Datenbindung zu verwenden, sind folgende Einstellungen erforderlich:

  1. Aktivieren Sie die Datenbindung in der build.gradle-Datei des App-Moduls:

android {
    ...
    dataBinding {
        enabled = true
    }
}

    2. Fügen Sie oben in der Layoutdatei Tags hinzu, <layout>um den Layoutinhalt zu umschließen:

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 布局内容 -->
</layout>

3. Holen Sie sich die gebundene Instanz in Aktivität oder Fragment:

// 在 Activity 中通过 setContentView 方法绑定布局
MyLayoutBinding binding = DataBindingUtil.setContentView(this, R.layout.my_layout);

// 在 Fragment 中通过 LayoutInflater 绑定布局
MyLayoutBinding binding = MyLayoutBinding.inflate(inflater, container, false);

Datenbindungsausdruck

Sie können Ausdruckssprachen in Layoutdateien verwenden, um gebundene Daten zu referenzieren und Vorgänge auszuführen, zum Beispiel:

  • Referenzieren Sie eine Variable oder Objekteigenschaft:

<TextView
    android:text="@{user.name}"
    ... />
  • Methodenaufruf ausführen:
<Button
    android:onClick="@{onClickListener.onButtonClick()}"
    ... />
  • Verwenden Sie bedingte Anweisungen und Schleifen:
<TextView
    android:text="@{user.isAdult ? `Adult` : `Child`}"
    ... />

<LinearLayout
    android:visibility="@{user.isAdmin ? View.VISIBLE : View.GONE}"
    ... />

<RecyclerView
    app:itemList="@{list}"
    ... />

Zwei-Wege-Bindung

        Bei der bidirektionalen Bindung handelt es sich um ein Datenbindungskonzept, das automatisch die Synchronisierung zwischen der Ansicht (UI) und dem Datenmodell (Modell) aufrechterhält. Ändert sich eine Variable in der Ansicht, wird auch das zugehörige Datenmodell aktualisiert; ändert sich umgekehrt der Wert des Datenmodells, wird die Ansicht entsprechend aktualisiert.

        DataBinding unterstützt auch die bidirektionale Bindung, die Änderungen an UI-Komponenten an der Datenquelle widerspiegelt. @=Eine bidirektionale Bindung kann über das Symbol erreicht werden :

<EditText
    android:text="@={user.name}"
    ... />

2. Beispiele

Beispiel 1: DataBinding implementiert Textbindung und Klickereignisse

 Hauptaktivität :

package com.example.databinding2;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;


import android.os.Bundle;

import com.example.databinding2.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding mainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        // 利用DataBinding绑定UI文本
        Food food = new Food("麻辣烫", (float) 4);
        // 利用DataBinding实现点击事件
        mainBinding.setOnClickListener(new OnClickListener(this));
        mainBinding.setFood(food);
    }
}

CountStart:

package com.example.databinding2;

public class CountStart {
    public static String getStar(float star){
        return star +"星";
    }
}

Essen: 

package com.example.databinding;

public class Food {
    public String name;
    public float star;
    public Food(String name,float star){
        this.name = name;
        this.star = star;
    }
}

 OnClickListener:

package com.example.databinding2;

import android.content.Context;
import android.view.View;
import android.widget.Toast;

public class OnClickListener {
    private Context mContext;
    public OnClickListener(Context context){
        mContext = context;
    }
    public void buttonOnClick(View view){
        Toast.makeText(mContext, "点击了提交!", Toast.LENGTH_SHORT).show();
    }

}

 Aktivität_main:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <!-- 实现设置文本       -->
        <import type = "com.example.databinding2.CountStart"/>
        <variable
            name="Food"
            type="com.example.databinding2.Food" />
        <!-- 实现点击事件       -->
        <variable
            name="OnClickListener"
            type="com.example.databinding2.OnClickListener" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">


        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_begin="365dp" />

        <ImageView
            android:src="@drawable/img"
            android:id="@+id/imageView"
            android:layout_width="300dp"
            android:layout_height="300dp"
            app:layout_constraintBottom_toTopOf="@+id/guideline2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.497"
            tools:srcCompat="@tools:sample/avatars" />

        <RatingBar
            android:id="@+id/ratingBar"
            android:layout_width="244dp"
            android:layout_height="54dp"
            android:max="5"
            android:rating="@{Food.star}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline2"
            app:layout_constraintVertical_bias="0.079" />

        <TextView
            android:id="@+id/textView"
            android:layout_width="129dp"
            android:layout_height="28dp"
            android:text="@{Food.name}"
            android:textSize="20sp"
            app:layout_constraintBottom_toTopOf="@+id/ratingBar"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.673"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.917" />

        <Button
            android:onClick="@{OnClickListener.buttonOnClick}"
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="160dp"
            android:text="提交"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.498"
            app:layout_constraintStart_toStartOf="parent" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{CountStart.getStar(Food.star)}"
            android:textSize="25sp"
            app:layout_constraintBottom_toTopOf="@+id/button"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/ratingBar" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

 build.gradle:


android {
    compileSdk 32

    defaultConfig {
        applicationId "com.example.databinding"
        minSdk 21
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        dataBinding {
            enabled = true
        }
    }

Operationsergebnis:

Beispiel 2: Bindung der sekundären Schnittstelle

  Aktivität_main:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <!-- 实现设置文本       -->
        <import type = "com.example.databinding2.CountStart"/>
        <variable
            name="Food"
            type="com.example.databinding2.Food" />
        <!-- 实现点击事件       -->
        <variable
            name="OnClickListener"
            type="com.example.databinding2.OnClickListener" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">


        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_begin="365dp" />

        <ImageView
            android:src="@drawable/img"
            android:id="@+id/imageView"
            android:layout_width="300dp"
            android:layout_height="300dp"
            app:layout_constraintBottom_toTopOf="@+id/guideline2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.497"
            tools:srcCompat="@tools:sample/avatars" />

        <TextView
            android:id="@+id/textView"
            android:layout_width="129dp"
            android:layout_height="28dp"
            android:text="@{Food.name}"
            android:textSize="20sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.673"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <include
            app:Food="@{Food}"
            app:OnClickListener="@{OnClickListener}"
            layout="@layout/sub_main"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.497"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline2"
            app:layout_constraintVertical_bias="0.253" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

sub_main: 

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="Food"
            type="com.example.databinding2.Food" />
        <!-- 实现点击事件       -->
        <variable
            name="OnClickListener"
            type="com.example.databinding2.OnClickListener" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <RatingBar
            android:id="@+id/ratingBar2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:rating="@{Food.star}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.438"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.065" />

        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="32dp"
            android:text="@{Food.name}"
            android:textSize="25sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.449"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/ratingBar2" />

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:text="提交"
            android:onClick="@{OnClickListener.buttonOnClick}"
            android:textSize="20sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.463"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView3" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

 Andere Codes und Laufeffekte sind die gleichen wie in Beispiel 1.

Beispiel 3. Beispiel für bidirektionale Bindung

 Hauptaktivität:

public class MainActivity extends AppCompatActivity {
    private ViewModel viewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 使用DataBindingUtil进行绑定
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        // 初始化ViewModel
        viewModel = new ViewModel();

        // 设置ViewModel到绑定对象中
        binding.setViewModel(viewModel);
    }
}

 ViewModel:

public class ViewModel extends BaseObservable {
    private String inputText;

    @Bindable
    public String getInputText() {
        return inputText;
    }

    public void setInputText(String inputText) {
        this.inputText = inputText;
        notifyPropertyChanged(BR.inputText);
    }
}

 Aktivität_main:

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="viewModel"
            type="com.example.ViewModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={viewModel.inputText}" />

        <!-- 其他视图 -->

    </LinearLayout>
</layout>

Beispiel 4: Verwenden Sie die Annotation @bindingAdapter, um Bilder zu laden

         @BindingAdapterAnmerkungen sind Anmerkungen, die zum Binden benutzerdefinierter Eigenschaften und Methoden in DataBinding verwendet werden. Durch Annotationen können wir eine statische Methode@BindingAdapter definieren,in der verschiedene benutzerdefinierte Datenbindungslogiken implementiert werden. 

Hauptaktivität : 

package com.example.databinding32;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;

import android.os.Bundle;

import com.example.databinding32.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding mainBinding =DataBindingUtil.setContentView(this,R.layout.activity_main);
        mainBinding.setNetworkImage("https://img-home.csdnimg.cn/images/20201124032511.png");
//        mainBinding.setLocalImage(R.drawable.ic_launcher_background);
    }
}

ImageBindingAdapter: 

package com.example.databinding32;

import android.text.TextUtils;
import android.widget.ImageView;

import androidx.databinding.BindingAdapter;

import com.squareup.picasso.Picasso;

public class ImageBindingAdapter {
    // 加载网络图片
    @BindingAdapter("image")
    public static void setImage(ImageView image,String url){
        if (!TextUtils.isEmpty(url)){
            Picasso.get()
                    .load(url)
                    .placeholder(R.drawable.ic_launcher_background)
                    .into(image);
        }else {
            image.setImageResource(R.drawable.ic_launcher_background);
        }

    }
    // 加载本地图片
    @BindingAdapter("image")
    public static void setImage(ImageView image,int resId){
        image.setBackgroundResource(resId);
    }
    // 如果没有url就加载本地图片
    @BindingAdapter(value = {"image","defaultImageResources"},requireAll = false)
    public static void setImage(ImageView image,String url,int resId){
        if (!TextUtils.isEmpty(url)){
            Picasso.get()
                    .load(url)
                    .placeholder(R.drawable.ic_launcher_background)
                    .into(image);
        }else {
            image.setBackgroundResource(resId);
        }
    }
}

Aktivität_main: 

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
    <variable
        name="networkImage"
        type="String" />
        <variable
            name="localImage"
            type="int" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="250dp"
            android:layout_height="250dp"
            app:image="@{networkImage}"
            app:defaultImageResources="@{localImage}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:srcCompat="@tools:sample/avatars" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

 Vorsichtsmaßnahmen:

Bei der Verwendung @BindingAdaptervon Anmerkungen müssen Sie auf folgende Punkte achten:

  1. Anmerkungsort: @BindingAdapterAnmerkungen können auf jede statische Methode angewendet werden.

  2. Methodenparameter: @BindingAdapterMethoden verfügen normalerweise über zwei Parameter: das Ansichtsobjekt (z. B. TextView) ImageViewund den zu bindenden Eigenschaftswert (z. B. Zeichenfolge, Bildressource usw.). Die Methode kann eine beliebige Anzahl von Parametern haben, die ersten beiden Parameter müssen jedoch das Ansichtsobjekt und die entsprechenden Eigenschaftswerte sein.

  3. Methodenbenennung: Um Eigenschaften zugeordnet zu werden, beginnen Methodennamen normalerweise "set"mit gefolgt vom Namen der zu bindenden Eigenschaft. Wenn Sie beispielsweise imageUrleine Eigenschaft binden möchten, könnte die Methode den Namen haben setImageUrl(ImageView view, String url).

  4. Parameteranmerkungen: Wenn @BindingAdaptereine Methode mehrere Parameter hat, können andere Anmerkungen verwendet werden, um verschiedene Parameter zu identifizieren. Beispielsweise können Sie @BindingAdapter({"imageUrl", "placeholder"})mit angeben, dass der erste Parameter der Methode imageUrldem Attribut und der zweite Parameter placeholderdem Attribut entspricht.

  5. Eigenschaftsname: In der Layoutdatei können Sie app:属性名称die Methode verwenden, um benutzerdefinierte Bindungseigenschaften festzulegen. Zum Beispiel app:imageUrl="@{viewModel.imageUrl}".

3. Zusammenfassung

        Die Hauptbedeutung der Verwendung von DataBinding besteht darin, den Datenbindungs- und UI-Aktualisierungsprozess in Android-Anwendungen zu vereinfachen und die Entwicklungseffizienz und Codelesbarkeit zu verbessern. Im Folgenden sind einige wichtige Auswirkungen der Verwendung von DataBinding aufgeführt:

1. Vereinfachen Sie die Codestruktur: Durch DataBinding können die Layoutdatei und die Datenquelle direkt gebunden werden, wodurch das Schreiben von mühsamem findViewById() und manuellem Dateneinstellungscode reduziert wird. Dies macht den Code prägnanter und klarer und reduziert Fehler, die durch die manuelle Aktualisierung der Benutzeroberfläche entstehen.

2. Reduzieren Sie Nullzeigerausnahmen: DataBinding verwendet eine nullsichere Ausdruckssprache, um durch Nulldaten verursachte Nullzeigerausnahmen zu vermeiden. Durch den Umgang mit Nullwerten in Ausdrücken gewährleisten Sie einen sicheren Zugriff und eine sichere Manipulation von Daten.

3. Leistung verbessern : Die Datenbindung kann eine Echtzeitbindung von Daten und Schnittstellen realisieren. Erst wenn sich die Daten ändern, wird die UI-Aktualisierung ausgelöst. Im Vergleich zur herkömmlichen manuellen Aktualisierungsmethode kann sie unnötige UI-Aktualisierungen effektiv reduzieren und die Anwendungseffizienz verbessern . Leistung und Reaktionsfähigkeit.

4. Unterstützung der bidirektionalen Bindung: DataBinding unterstützt die bidirektionale Bindung, dh die Änderungen des Benutzers an der Benutzeroberfläche können in der Datenquelle widergespiegelt werden. Dadurch können Sie Formulareingaben, Statuswechsel und andere Funktionen einfach implementieren, ohne dass zusätzliche Rückrufe oder Listener erforderlich sind.

5. Verbessern Sie die Lesbarkeit des Codes : Mit DataBinding können Sie UI-bezogenen Code und Geschäftslogik trennen, wodurch die Codestruktur klarer wird und die Lesbarkeit und Wartbarkeit des Codes verbessert wird. Entwickler können sich auf die Verarbeitung von Daten und Logikebenen konzentrieren, ohne Schnittstellenelemente direkt zu manipulieren.

        Kurz gesagt, die Verwendung von DataBinding kann den Datenbindungsprozess vereinfachen, die Leistung und Lesbarkeit des Codes verbessern, Fehler reduzieren und flexiblere Datenbindungs- und bidirektionale Bindungsfunktionen bereitstellen. Es handelt sich um ein leistungsstarkes Tool, das die Effizienz und Benutzererfahrung bei der Entwicklung von Android-Anwendungen verbessern kann.

Fortgesetzt werden. . . . . .

おすすめ

転載: blog.csdn.net/A125679880/article/details/131756222