Android(安卓)Jetpack组件之DataBinding详解
Databinding:双向数据绑定库:
1.什么是Databinding:
数据绑定,可以直接在xml中绑定数据并实现一些处理逻辑,实时动态刷新数据。它的功能强大,可以节省很多手写的代码,而且性能也很好。 谷歌官方给出的是这样一个定义: The Data Binding Library is a support library that allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically. 翻译过来大概意思是: Databinding是一个支持库,允许您使用声明格式(而不是以编程方式)将布局中的UI组件绑定到应用程序中的数据源;
2.DataBinding的优点和缺点(有点太多了,就简单列举几个可以看得见得)
DataBinding:在MVVM设计模式上大量使用,主要用于Xml与ViewModel的数据进行双向绑定,界面的数据更新以及用户操作的响应. 优点: 1.性能高(性能比直接使用findViewById要高) 2.大量减少Activity内的代码。 3.数据能够单向或者双向绑定到布局文件当中,这样有助于防止内存泄露,而且能够自动进行空检测以避免空指针异常 4.DataBinding这个库占得内存比较小(与ButterKnife相比) 缺点:DataBinding在编写xml布局问件时,不太友好,代码提示,自动补全有点差
3.怎么使用DataBinding:
1.在我们创建项目模块时,自带支持的DataBinding,只需要在相应的build.gradle中android下加上几行代码就可以使用了:
dataBinding { enabled = true }
2.设置布局:将布局的xml改为最外层为标签
1).将鼠标的光标放在最外层的布局上,同时按下Alt+Ente
2).选择Convert to data binding layout
当我们设置好之后布局将会变成这个样子的
4.Databinding的具体使用:
1).布局写法:
<?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"> <data> <import type="com.cloudtp.conference.mvvm_databinding.viewmodel.MainViewModel" /> <!-- import:type中这里我写入的是ViewModel的全路径, 当然你也可以写入项目的R文件的全路径等等 , 这个根据自己的当时的需求 也可以同时设置多个import和variable--> <variable name="viewModel" type="MainViewModel" /> <!-- name:是标签名,也是type所指类的别名 type:代表你标签名所指向的类, 因为我们这里指向了我们的ViewModel下面我们需要ViewModel中的数据,可以直接去取--> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/one_text" android:layout_width="match_parent" android:layout_height="45dp" android:gravity="center" android:text="@{`姓名 :`+String.valueOf(viewModel.name)}" android:visibility="@{((viewModel.age==0)?View.INVISIBLE : View.VISIBLE)}"/> <TextView android:id="@+id/two_text" android:layout_below="@+id/one_text" android:layout_width="match_parent" android:layout_height="45dp" android:gravity="center" android:text="@{`性别 :`+String.valueOf(viewModel.sex)}" android:visibility="@{((viewModel.age==0)?View.INVISIBLE : View.VISIBLE)}"/> <TextView android:id="@+id/three_text" android:layout_below="@id/two_text" android:layout_width="match_parent" android:layout_height="45dp" android:gravity="center" android:text="@{`年龄 :`+String.valueOf(viewModel.age)}" android:visibility="@{((viewModel.age==0)?View.INVISIBLE : View.VISIBLE)}"/> <Button android:layout_below="@id/three_text" android:layout_width="match_parent" android:layout_marginTop="50dp" android:layout_marginRight="50dp" android:layout_marginLeft="50dp" android:text="更新数据" android:layout_height="45dp" android:onClick="@{viewModel.onClickData}"/> <ImageView android:layout_width="100dp" android:layout_marginTop="40dp" android:layout_gravity="center_horizontal" android:layout_height="100dp" app:image="@{viewModel.image}"/> </LinearLayout></layout>
2).MainActivity中的写法
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //绑定类的名称是基于布局文件的名称生成的, 它是将布局文件名开头大写并加上“Binding”而成。 //如果布局文件最外层不是 标签,将无法使用这种方式绑定布局,和获取资源文件 ActivityMainBinding b =DataBindingUtil.setContentView(this,R.layout.activity_main); //绑定数据 b.setViewModel(new MainViewModel()); //获取资源id,可以直接通过 b . 加上 资源id //(b:这里指上面的ActivityMainBinding) //例如: //b.oneText.setText("典典"); }}
3).MainViewModel(这里的ViewModel只是一个普通的类,用于设置实体类数据及获取实体类数据,并不是MVVM中的Viewmodel)
public class MainViewModel { public ObservableField<String> name = new ObservableField<>(); public ObservableField<String> sex = new ObservableField<>(); public ObservableField<Integer> age = new ObservableField<>(); public ObservableField<Integer> image=new ObservableField<>(); private UseDao userDao = new UseDao(); @BindingAdapter({"image"}) public static void setImage(ImageView imageView, int userfaceResId){ imageView.setImageResource(userfaceResId); } //点击事件 public void onClickData(View view){ userDao.getUser(new Handler.Callback() { @Override public boolean handleMessage(Message message) { UserBean userBean=(UserBean)message.obj; name.set(userBean.getName()); sex.set(userBean.getSex()); age.set(userBean.getAge()); image.set(userBean.getImage()); return true; } }); }}
这里使用ObservableField:它是一个类中的单独的字段做观察,它对字段做了一层封装,类似java中的装箱;成为了一个对象级的存在,在数据发生改变时UI会收到通知(推荐大家使用LiveData,相比ObservableField,LiveData更加强大)
如果你认为DataBinding只是简单的代替FindViewById(),那你就真的小看DataBinding,DataBinding的功能不单单只是查询资源id
@BindingAdapter(Databinding注解)
当控件里面没有提供某个属性的setXXX方法,又或者这个setXXX方法名字我们不喜欢,还有就是明明就是设置控件的某个属性的,但方法名却不是以set开头的,这些情况我们可以使用BindingAdapter这个强大的注解。
使用方法如下所示:
布局中: 代码中: @BindingAdapter({"image"}) public static void setImage(ImageView imageView, int userfaceResId){ imageView.setImageResource(userfaceResId); }
在我们使用RecycleView时,我们可以直接听过这个注解设置LayoutManager以及Adapter
此外DataBinding在Xml布局文件中还支持一下运算符:
1.算术 + - / * %2.字符串合并 +3.逻辑 && ||4.二元 & | ^5.一元 + - ! ~6.移位 >> >>> <<7.比较 == > < >= <=8.Instanceof9.Grouping ()10.character, String, numeric, null11.Cast12.方法调用13.Field 访问14.Array 访问 []15.三元 ?:
下面给大家提一点使用DataBinding的小建议:
1.不要拒绝 findViewById()
DataBinding与findViewById不互斥,如果在特殊情况下使用findViewById()比较方便,就不要拒绝了
2.xml中的表达式尽量简单
xml 文件中不要出现过于复杂业务逻辑,只出现简单的 UI 相关的表达式。不要以为Data Binding是万能的,而想尽办法把逻辑写在xml中。往往这个时候你就应该将逻辑写在绑定的ViewModel里面。
3.注意clean
有时候因为修改接口等原因要修改绑定的bean类,这时候偶尔会遇到一些神奇的bug。不要慌张,直接clean一下项目再make project一次往往就好了
过多的也不赘述了,如果还有什么问题大家可以参阅一下
DataBinding官方文档:https://developer.android.google.cn/topic/libraries/data-binding/
更多相关文章
- 一句话锁定MySQL数据占用元凶
- Android中 一些维持状态的经验
- Android系统剪贴板(ClipboardManager)的简单使用
- android 解决java.nio.BufferOverflowException 异常
- Android(安卓)string-array数据源简单使用
- Android中Adapter嵌套Adapter、ListView嵌套GridView时的内层Ada
- FFmpeg 音频编码(PCM数据编码成AAC android)
- Android下 SQLite的使用
- Android仿IOS回弹效果 支持任何控件