Primeiros passos com Jetpack: DataBinding

Índice

1. Introdução ao DataBinding

Definir vinculação de dados

expressão de ligação de dados

Ligação bidirecional

2. Exemplos

Exemplo 1: DataBinding implementa vinculação de texto e eventos de clique

 Atividade principal :

ContagemInício:

Comida: 

 OnClickListener:

 atividade_principal:

 construir.gradle:

resultado da operação:

Exemplo 2: Ligação da interface secundária

  atividade_principal:

sub principal: 

Exemplo 3. Exemplo de ligação bidirecional

 Atividade principal:

 Modelo de visualização:

 atividade_principal:

Exemplo 4: use a anotação @bindingAdapter para carregar imagens

Atividade principal : 

Adaptador ImageBinding: 

atividade_principal: 

 Precauções:

3. Resumo

1. Introdução ao DataBinding

        DataBinding é uma biblioteca para vinculação de dados concisa e eficiente em aplicativos Android. Ele permite que os desenvolvedores vinculem declarativamente os componentes da UI às fontes de dados, atualizando automaticamente os dados na interface e simplificando o processo de escrita de código relacionado à UI.

Definir vinculação de dados

Para usar a vinculação de dados, são necessárias as seguintes configurações:

  1. Habilite a vinculação de dados no arquivo build.gradle do módulo do aplicativo:

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

    2. Adicione tags na parte superior do arquivo de layout <layout>para agrupar o conteúdo do layout:

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

3. Obtenha a instância vinculada em Activity ou Fragment:

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

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

expressão de ligação de dados

Você pode usar linguagens de expressão em arquivos de layout para fazer referência a dados vinculados e realizar operações, por exemplo:

  • Faça referência a uma variável ou propriedade de objeto:

<TextView
    android:text="@{user.name}"
    ... />
  • Executar chamada de método:
<Button
    android:onClick="@{onClickListener.onButtonClick()}"
    ... />
  • Use instruções condicionais e loops:
<TextView
    android:text="@{user.isAdult ? `Adult` : `Child`}"
    ... />

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

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

Ligação bidirecional

        A vinculação bidirecional é um conceito de vinculação de dados que mantém automaticamente a sincronização entre a visualização (UI) e o modelo de dados (Modelo). Quando uma variável muda na visão, o modelo de dados associado também é atualizado; inversamente, quando o valor do modelo de dados muda, a visão é atualizada de acordo.

        DataBinding também oferece suporte à ligação bidirecional, que reflete alterações nos componentes da UI para a fonte de dados. @=A ligação bidirecional pode ser obtida através do símbolo:

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

2. Exemplos

Exemplo 1: DataBinding implementa vinculação de texto e eventos de clique

 Atividade principal :

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

ContagemInício:

package com.example.databinding2;

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

Comida: 

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

}

 atividade_principal:

<?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>

 construir.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
        }
    }

resultado da operação:

Exemplo 2: Ligação da interface secundária

  atividade_principal:

<?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 principal: 

<?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>

 Outros códigos e efeitos de execução são iguais ao Exemplo 1.

Exemplo 3. Exemplo de ligação bidirecional

 Atividade principal:

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

 Modelo de visualização:

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

 atividade_principal:

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

Exemplo 4: use a anotação @bindingAdapter para carregar imagens

         @BindingAdapterAnotações são anotações usadas para vincular propriedades e métodos personalizados em DataBinding. Por meio@BindingAdapterde anotações, podemos definir um método estático no qual várias lógicas personalizadas de ligação de dados são implementadas. 

Atividade principal : 

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

Adaptador ImageBinding: 

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

atividade_principal: 

<?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>

 Precauções:

Ao usar @BindingAdapteranotações, você precisa prestar atenção aos seguintes pontos:

  1. Localização da anotação: @BindingAdapteras anotações podem ser aplicadas a qualquer método estático.

  2. Parâmetros do método: @BindingAdapterOs métodos geralmente têm dois parâmetros: o objeto de visualização (por exemplo TextView, ImageView) e o valor da propriedade a ser vinculado (por exemplo, string, recurso de imagem, etc.). O método pode ter qualquer número de parâmetros, mas os dois primeiros parâmetros devem ser o objeto de visualização e os valores de propriedade correspondentes.

  3. Nomenclatura de métodos: para serem associados a propriedades, os nomes dos métodos geralmente "set"começam com seguido do nome da propriedade a ser vinculada. Por exemplo, se você quiser vincular imageUrluma propriedade, o método poderá ser nomeado setImageUrl(ImageView view, String url).

  4. Anotações de parâmetros: quando @BindingAdapterum método possui vários parâmetros, outras anotações podem ser usadas para identificar parâmetros diferentes. Por exemplo, você pode usar @BindingAdapter({"imageUrl", "placeholder"})para especificar que o primeiro parâmetro do método corresponde ao imageUrlatributo e o segundo parâmetro corresponde ao placeholderatributo.

  5. Nome da propriedade: no arquivo de layout, você pode usar app:属性名称o método para definir propriedades de ligação personalizadas. Por exemplo, app:imageUrl="@{viewModel.imageUrl}".

3. Resumo

        O principal significado do uso do DataBinding é simplificar o processo de vinculação de dados e atualização da IU em aplicativos Android e melhorar a eficiência do desenvolvimento e a legibilidade do código. A seguir estão algumas implicações importantes do uso de DataBinding:

1. Simplifique a estrutura do código: por meio do DataBinding, o arquivo de layout e a fonte de dados podem ser vinculados diretamente, reduzindo assim a necessidade de escrever o tedioso findViewById() e definir manualmente o código de dados. Isso torna o código mais conciso e claro e reduz erros causados ​​pela atualização manual da IU.

2. Reduza exceções de ponteiro nulo: DataBinding usa uma linguagem de expressão segura para nulos para evitar exceções de ponteiro nulo causadas por dados nulos. Ao lidar com valores nulos em expressões, você garante acesso e manipulação segura de dados.

3. Melhorar o desempenho : a vinculação de dados pode realizar vinculação de dados e interface em tempo real. Somente quando os dados mudam, a atualização da interface do usuário será acionada. Em comparação com o método tradicional de atualização manual, pode efetivamente reduzir a atualização desnecessária da interface do usuário e melhorar a eficiência do aplicativo • desempenho e capacidade de resposta.

4. Suporte à ligação bidirecional: DataBinding oferece suporte à ligação bidirecional, ou seja, as modificações do usuário na IU podem ser refletidas na fonte de dados. Isso permite implementar facilmente entrada de formulário, alternância de estado e outras funções sem a necessidade de retornos de chamada ou ouvintes adicionais.

5. Melhorar a legibilidade do código : Usando DataBinding, o código relacionado à UI e a lógica de negócios podem ser separados, tornando a estrutura do código mais clara e melhorando a legibilidade e a manutenção do código. Os desenvolvedores podem se concentrar no processamento de dados e níveis lógicos sem manipular diretamente os elementos da interface.

        Resumindo, o uso de DataBinding pode simplificar o processo de vinculação de dados, melhorar o desempenho e a legibilidade do código, reduzir erros e fornecer vinculação de dados mais flexível e funções de vinculação bidirecional. É uma ferramenta poderosa que pode melhorar a eficiência do desenvolvimento de aplicativos Android e a experiência do usuário.

Continua. . . . . .

Acho que você gosta

Origin blog.csdn.net/A125679880/article/details/131756222
Recomendado
Clasificación