引言
之前对databinding有了基础的运用与介绍,但databinding的用处不单单在于Text的绑定,接下来就一起看看吧!
意义:让布局文件承担了部分原本属于页面的工作,使页面与布局耦合度进一步降低。允许用户界面(UI)元素(如文本框、列表、按钮等)与数据源(如数据库、对象、XML 文件等)之间建立自动同步的双向或单向绑定关系。这种技术可以减少代码量,提高开发效率,并且使得数据的更新和UI的更新更加直观和自动化。
应用
基本应用
根据一个例子来理解吧!
- 新建一个活动,活动当中放置一个图片和两个
TextView
控件,我们之前为TextView
设置内容都是在主活动当中先获取到控件,在使用setText()
方法设置,现在我们试试不在活动当中,此时的布局文件大家都会写,在这里就不展示了 - 打开build.gradle文件,添加以下内容,注意不要忘记
sync now
- 鼠标位于布局文件的最前端点击alt+回车,就会出现以下内容,我们需要添加红色边框部分内容
<data>
:这个元素定义了布局文件中可以使用的数据源。<variable
:这个元素定义了一个变量,它可以在布局文件中被引用。name="idol"
:这是变量的名称,在布局文件中可以通过这个名称来引用变量。type="com.example.databinding.Idol"
:这是变量的类型,它指定了变量的数据类型。在这个例子中,Idol
是一个Java类,它可能定义了一些属性,名字、等级,这些属性可以在布局文件中被绑定到UI组件上。
- 对主活动进行修改
ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
Idol idol = new Idol("熊大", "五星");
activityMainBinding.setIdol(idol);
activityMainBinding
:这是一个变量,它存储了绑定类的实例,可以通过这个变量访问布局文件中定义的视图和变量。DataBindingUtil.setContentView
:这是一个静态方法,用于将布局文件绑定到当前的Activity。它返回一个绑定类(在这个例子中是ActivityMainBinding
)的实例,这个绑定类是由Data Binding库根据布局文件自动生成的。setIdol
:这是在ActivityMainBinding
类中定义的一个方法,它用于将Idol
对象绑定到布局文件中定义的变量idol
上。
- 对布局文件进行修改
接下来运行程序:
Important标签和事件绑定
- Important标签
若在我们创建的时候有一个值为整型怎么办,例如在Idol当中将star设置为整型,此时我们就需要将整形转化为字符串类型,创建一个类
public class StarUtils {
public static String getStar(int star) {
switch (star) {
case 1:
return "一星";
case 2:
return "二星";
case 3:
return "三星";
case 4:
return "四星";
}
return "";
}
}
修改xml文件
<data>
<variable
name="idol"
type="com.example.databinding.Idol" />
<import type="com.example.databinding.StarUtils"/>
</data>
<TextView
android:id="@+id/dengji"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{StarUtils.getStar(idol.star)}"
android:textSize="25sp" />
此时在创建对象的时候:
Idol idol = new Idol("熊大", 1);
运行程序,也会得到相应的结果。
<import>
:这是Data Binding布局文件中的一个XML标签,用于导入Java类。type
:这是<import>
标签的一个属性,用于指定要导入的类或包的全限定名。
- 与事件绑定
设置一个按钮,为点击按钮注册事件
public class EventHander {
private Context context;
public EventHander(Context context) {
this.context = context;
}
public void buttonOnclick(View view) {
Toast.makeText(context, "喜欢", Toast.LENGTH_SHORT).show();
}
}
将这个类添加到绑定资源当中
<data>
<variable
name="idol"
type="com.example.databinding.Idol" />
<variable
name="eventbutton"
type="com.example.databinding.EventHander" />
<import type="com.example.databinding.StarUtils"/>
</data>
按钮控件进行添加绑定
android:onClick="@{eventbutton.buttonOnclick}"
此时运行程序,当按下按钮
二级页面的绑定
标签引用二级页面
我们将上面布局的按钮进行删除,将两个TextView控件放在一个xml文件之下,使主活动的xml文件引用这个xml文件,此时我们就不需要在一级页面将star进行转换,将Import标签进行删除,并对引用布局部分进行标签传递修改
<include layout="@layout/sub"
app:idol="@{idol}"/>
在二级页面当中TextView的代码与之前的一级页面一样,注意不要忘记添加资源部分。
此时运行程序的结果与之前一样。
自定义BandingAdapter
BindingAdapter
是 Android Data Binding 库中的一个特性,它允许开发者定义自定义的绑定适配器,从而将属性或方法绑定到 XML 布局文件中的视图上。这些适配器可以用于处理视图的属性,如图片加载、文本格式化、视图可见性等,使得布局文件更加简洁,并且将视图逻辑与业务逻辑分离。
加载网络图片
接下来尝试自定义BandingAdapter加载网络图片:
使用DataBinding的必要操作就不再赘述了,我们在布局当中放置一个ImageView用来放置图片,制定一个BandingAdapter
public class ImageViewbindingAdapter {
//加载网络图片
@BindingAdapter("image")
public static void setImage(ImageView imageView, String url) {
if (!TextUtils.isEmpty(url)) {
Picasso.get()
.load(url)
.placeholder(R.drawable.draw1)
.into(imageView);
} else {
imageView.setBackgroundColor(Color.GRAY);
}
}
}
-
添加方法注解:
@BindingAdapter("image")
:这个注解将setImage
方法标记为一个 Binding Adapter,并且指定了一个绑定属性名image
。这意味着在 XML 布局文件中,你可以使用app:image
属性来调用这个方法。
-
参数:
ImageView imageView
:这是一个ImageView
对象的引用,它将被用来加载图片。String url
:这是一个字符串参数,代表要加载的图片的网络 URL。
-
方法逻辑:
if (!TextUtils.isEmpty(url))
:这个条件检查传入的 URL 是否为空或 null。TextUtils.isEmpty
是 Android 提供的一个工具方法,用于检查字符串是否为空。Picasso.get().load(url)
:如果 URL 不为空,方法使用 Picasso 图片加载库来加载网络图片。Picasso 是一个流行的第三方库,用于简化图片的异步加载和缓存。
使用 Picasso 图片加载库要添加依赖:
implementation("com.squareup.picasso:picasso:2.71828")
.placeholder(R.drawable.draw1)
:这个方法链设置了一个占位图,它将在图片加载完成之前显示在ImageView
上。R.drawable.draw1
应该是一个有效的资源 ID,指向你的应用资源中的一个图片文件。.into(imageView)
:最后,into
方法将加载的图片绑定到传入的ImageView
上。else
分支:如果 URL 为空,方法将ImageView
的背景色设置为灰色,这提供了一种默认的视觉反馈。
看看布局文件的修改:
<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" />
</data>
<LinearLayout
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<ImageView
android:id="@+id/image"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
app:image="@{networkImage}" />
</LinearLayout>
</layout>
主活动中的代码:
ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
activityMainBinding.setNetworkImage("https://i-blog.csdnimg.cn/direct/97ca7ca4a5bb430b829b0d03b3a00887.png#pic_center");
调用逻辑
- 设置内容视图: 在你的 Activity 中,你使用
DataBindingUtil.setContentView
方法来设置内容视图,这个方法会解析布局文件并创建相应的视图绑定类ActivityMainBinding
。 - 绑定数据: 通过
activityMainBinding.setNetworkImage(...)
方法,你将网络图片的 URL 传递给绑定类。这里的setNetworkImage
方法应该是在绑定类中定义的,用于设置networkImage
变量的值。 - 数据绑定: 当
networkImage
变量的值被设置后,Data Binding 库会自动将这个值传递给ImageView
的app:image
属性。 - 图片加载: 由于
ImageView
的app:image
属性绑定到了networkImage
变量,当变量的值发生变化时,Data Binding 库会调用setImage
方法来加载图片。setImage
方法会检查 URL 是否为空,如果不为空,则使用 Picasso 加载图片,并设置一个占位图。 - 错误处理: 如果 URL 为空,
setImage
方法会将ImageView
的背景色设置为灰色,作为错误或占位的指示。
加载本地图片
相信你已经大致知道如何对代码进行修改
首先对布局文件进行修改:
//添加文件引用变量
<variable
name="LocalImage"
type="int" />
//此时控件的引用进行修改
app:image="@{LocalImage}"
对BandingAdapter进行修改,此时我们传入的数据一个发生了变化,从而使用方法的重载:
@BindingAdapter("image")
public static void setImage(ImageView imageView, int resID) {
imageView.setImageResource(resID);
}
在主活动当中将本地图片传入:
activityMainBinding.setLocalImage(R.drawable.draw2);
此时运行程序:
此时图片就加载上去了
选择性添加
我们若是要先加载网络图片,当网络图片为空,我们想再加载本地图片,则我们就可以添加注解时添加两个:
布局文件:
<ImageView
android:id="@+id/image"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
app:image="@{networkImage}"
app:default="@{LocalImage}"/>
在BandingAdapter类当中:
先来看看注解:
我们可以看到原本定义的就是字符串类型,requireAll()
代表的是所有在 value
数组中指定的属性都必须有有效的值。如果任何一个属性没有被赋值,那么绑定方法将不会被执行,如果任何一个属性没有被赋值,那么绑定方法将不会被执行。源代码默认为true,我们将其设置为false,即无需对注解所需的数据都进行传入
@BindingAdapter(value = {"image","default"}, requireAll = false)
public static void setImage(ImageView imageView, String url, int resID) {
if (!TextUtils.isEmpty(url)) {
Picasso.get()
.load(url)
.placeholder(R.drawable.draw1)
.into(imageView);
} else {
imageView.setImageResource(resID);
}
}
此时运行程序:
网络图片就加载出来了,当我们将绑定网络图片代码删除,就会加载本地的图片。
文章到这里就结束了!