LZ-Says:每一次的选择,都将面临更多的希望,加油,而今迈步重头跃。。。

前言

前段时间,完结了一篇Data Binding前篇,地址如下:

Android Study 之 如何通过Data Binding提升撸码逼格(基础篇)

而今,我们一起来学习下,有关Data Binding进阶用法。

发车了,来来来

一、notifyPropertyChanged方式更新指定数据

首先,来简单介绍下Observable:

  • Observable 基于观察者模式更新;

  • 它的出现,便是为了解决当我们的实体发生改变时,UI即时刷新。

先来一个小例子:

  • 假设我们现在有一个User对象,当修改其中一个属性,使其引用的部分更新为修改后的值。

那么针对这个需求,我们使用Observable即可分分钟搞定。这里,大家可以简单理解为,这个就是负责数据更新~

下面来个Demo试试:

Step 1: 实体类继承BaseObservable

package com.hlq.databindingdemo.bean;import android.databinding.BaseObservable;
import android.databinding.Bindable;import com.hlq.databindingdemo.BR;/*** author : HLQ* e-mail : 925954424@qq.com* time   : 2018/02/22* desc   : BaseObservable 学习了解* version: 1.0*/
public class ClassBean extends BaseObservable {private String classNo;private String classNum;private String className;public ClassBean(String className) {this.className = className;}public ClassBean(String className, String classNum) {this.className = className;this.classNum = classNum;}public ClassBean(String classNo, String classNum, String className) {this.classNo = classNo;this.classNum = classNum;this.className = className;}@Bindablepublic String getClassNo() {return classNo;}public void setClassNo(String classNo) {this.classNo = classNo;}@Bindablepublic String getClassName() {return className;}public void setClassName(String className) {this.className = className;}@Bindablepublic String getClassNum() {return classNum;}public void setClassNum(String classNum) {this.classNum = classNum;}
}

Step 2: 为字段设置notifyPropertyChanged

这里,老铁需要谨记一点即可:

想让谁更新,就给谁设置notifyPropertyChanged(BR.字段名)。

而设置的规则,简单如下:

例如,想为ClassBean中classNo设置更新,那么只需要在setClassNo中添加notifyPropertyChanged(BR.classNo);即可,其他同理。

那么,本小节演示所有字段设置更新,那么对应的代码段如下:

    public void setClassNo(String classNo) {this.classNo = classNo;notifyPropertyChanged(BR.classNo);}public void setClassName(String className) {this.className = className;notifyPropertyChanged(BR.className);}public void setClassNum(String classNum) {this.classNum = classNum;notifyPropertyChanged(BR.classNum);}

而为了突出演示效果,这里添加一个EditText,用于在用户输入数据时,动态修改实体,从而进行UI即时刷新。

同样,也需要初始化以及设置事件,下面一起看看:

    private ActivityObservableBinding mBinding;private ClassBean mClassBean = new ClassBean("001", "100", "A1T105");@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mBinding = DataBindingUtil.setContentView(this, R.layout.activity_observable);mBinding.setClassX(mClassBean);mBinding.setPresenter(new Presenter());}public class Presenter {public void onTextChanged(CharSequence s, int start, int before, int count) {mClassBean.setClassNo("No:" + s);mClassBean.setClassNum("Num:" + s);mClassBean.setClassName("Name:" + s);}}

xml当中也只是简单的调用事件以及赋值,简单贴出部分代码:

<EditTextstyle="@style/titleStyle"android:onTextChanged="@{presenter.onTextChanged}" /><TextViewstyle="@style/contentStyle"android:text="展示数据更新-notifyPropertyChanged" /><TextViewstyle="@style/titleStyle"android:text="@{classX.classNo}" /><TextViewstyle="@style/titleStyle"android:text="@{classX.classNum}" /><TextViewstyle="@style/titleStyle"android:text="@{classX.className}" />

先来看一波效果:

有的小伙伴说了,这TMD太麻烦了,我实体类属性字段有很多肿么办?一个个添加吗?

当然不。身为程序猿猿,能偷懒,当然不傻傻干。瞧好吧您呐~

二、notifyChange方式更新全部数据

基于上节,本次单独定义一个实体类,用于展示更新全部数据。

package com.hlq.databindingdemo.bean;import android.databinding.BaseObservable;
import android.databinding.ObservableBoolean;/*** author : HLQ* e-mail : 925954424@qq.com* time   : 2018/02/22* desc   : notifyChange 更新所有数据* version: 1.0*/
public class LoveBean extends BaseObservable {private String youSelf;private String mySelf;private ObservableBoolean isTrueLove = new ObservableBoolean();public LoveBean(String youSelf, String mySelf, boolean trueLove) {this.youSelf = youSelf;this.mySelf = mySelf;isTrueLove.set(trueLove);}public String getYouSelf() {return youSelf;}public void setYouSelf(String youSelf) {this.youSelf = youSelf;}public String getMySelf() {return mySelf;}public void setMySelf(String mySelf) {this.mySelf = mySelf;}public ObservableBoolean getIsTrueLove() {return isTrueLove;}public void setIsTrueLove(boolean isTrueLove) {this.isTrueLove.set(isTrueLove);notifyChange();}
}

这里需要注意,只需要为一个单独属性字段设置notifyChange即可实现所有数据均实现更新。

下面开始对应的初始化:

    private LoveBean mLoveBean = new LoveBean("Who are you", "H.L.Q.", true);...mBinding.setLove(mLoveBean);...mLoveBean.setYouSelf("Who are you?" + s);mLoveBean.setMySelf("H.L.Q." + s);mLoveBean.setIsTrueLove(!mLoveBean.getIsTrueLove().get());

一起来看看效果:

这里LZ再啰嗦一句,俩者区别在于:

  • 如果仅仅是想更新部分属性字段,只需要在要更新的属性字段set方法下添加notifyPropertyChanged(BR.属性字段名);

  • 如果是仅仅想更新全部属性字段,则随便在某个set的方法下添加notifyChange()。

当然,Data Binding的神奇之处还有很多,比如,它为我们提供了对应的一系列ObservableField,那么,下面,让我们一起去看看吧~

三、ObservableField Study

  • 有的小伙伴说了,忒麻烦,忒麻烦,我连get/set都不想搞,怎么破?

  • So easy~ 那都不叫事儿~

简单说一下ObservableField是什么鬼:

  • 首先,ObservableField是归属于Observable旗下,作用就是为了简化操作,避免你写多余的get/set,当然喽,优点并不止这些;

  • 其次,Observable旗下包含了很多类似ObservableField的家伙,例如:ObservableInt、ObservableBoolean等。

  • 如何使用呢?你怎么使用String、int等,就怎么使用这个。说白了,就是一个配套的家伙。

那么接下来,简单搞俩个Demo熟悉下使用:

Example One:先来个ObservableField练练手

Step 1: 定义实体类

import android.databinding.ObservableField;/*** author : HLQ* e-mail : 925954424@qq.com* time   : 2018/02/23* desc   : ObservableField 首战* version: 1.0*/
public class MissBean {public final ObservableField<String> missWho = new ObservableField<>();public final ObservableField<String> missYou = new ObservableField<>();}

Step 2: 布局引用

引入命名空间。

<data><variablename="missBean"type="com.hlq.databindingdemo.bean.MissBean" />
</data>

设置对应值。

<TextViewstyle="@style/titleStyle"android:text="@{missBean.missWho}" /><TextViewstyle="@style/titleStyle"android:text="@{missBean.missYou}" />

Step 3: Activity中初始化 - 赋值

mMissBean = new MissBean();
mMissBean.missWho.set("在思念谁?");
mMissBean.missYou.set("在思念你~");
mBinding.setMissBean(mMissBean);

Step 4: 查看效果

有的小伙伴说了,那我如果想取值呢?怎么弄?

一张图包教包会~ 再不会打死你~!

Example Two:再来个稍稍复杂的玩玩

Step 1: 定义我们实体类

package com.hlq.databindingdemo.bean;import android.databinding.ObservableBoolean;
import android.databinding.ObservableField;
import android.databinding.ObservableInt;/*** author : HLQ* e-mail : 925954424@qq.com* time   : 2018/05/08* desc   : Observable Field 实体类* version: 1.0*/
public class ObservableFieldBean {public ObservableField<String> filedName = new ObservableField<>();public ObservableInt fileAge = new ObservableInt();public ObservableBoolean fileStore = new ObservableBoolean();}

可以看到,我们这次不仅仅使用了ObservableField,还有ObservableInt以及ObservableBoolean,用法是不是很Easy?

Step 2: 引入命名空间,赋值

<data><variablename="filedBean"type="com.hlq.databindingdemo.bean.ObservableFieldBean" />
</data>

接下来赋值:

<TextViewstyle="@style/contentStyle"android:text="Observable Field" /><TextViewstyle="@style/titleStyle"android:text="@{filedBean.filedName}" /><TextViewstyle="@style/titleStyle"android:text='@{"年纪:"+filedBean.fileAge}' /><TextViewstyle="@style/titleStyle"android:text='@{"结果为:"+filedBean.fileStore}' />

Step 3: 初始化

mFiledBean = new ObservableFieldBean();
mFiledBean.filedName.set("贺大大");
mFiledBean.fileAge.set(22);
mFiledBean.fileStore.set(true);
mFieldBinding.setFiledBean(mFiledBean);

Step 4: 查看演示效果

四、ObservableArrayList Study

Step 1: 引入命名空间,声明类型

<data><import type="android.databinding.ObservableArrayList" /><variablename="loveList"type="ObservableArrayList&lt;String>" /></data>

这里需要注意,指定type时,ObservableArrayList类型里面不能包含<,而是通过 &lt ; 代替

Step 2: 赋值

<TextViewstyle="@style/contentStyle"android:text="ObservableArrayList Study" /><TextViewstyle="@style/titleStyle"android:text="@{loveList.get(0)}" /><TextViewstyle="@style/titleStyle"android:text="@{loveList.get(1)}" />

是不是很Easy,直接通过下标去访问即可。

Step 3: 查看演示效果

五、ObservableMap Study

Step 1: 布局添加引用

<data><import type="android.databinding.ObservableMap" /><variablename="loveMap"type="ObservableMap&lt;String,String>" /></data>

Step 2: 赋值

<TextView
    style="@style/contentStyle"android:text="ObservableArrayMap Study" /><TextView
    style="@style/titleStyle"android:text='@{loveMap["name"]}' /><TextView
    style="@style/titleStyle"android:text='@{loveMap["age"]}' />

Step 3: 初始化

ObservableMap<String, String> testMap = new ObservableArrayMap<>();
testMap.put("name", "贺大宝,心情不美丽");
testMap.put("age", "22的年龄,啧啧");
mFieldBinding.setLoveMap(testMap);

Step 4: 查看效果演示图

六、RecyclerView与DataBinding使用

目前的RecyclerView可谓火爆了半边天,试问,现在还是谁没用过?

先撸一波效果图~

首先,我们来回顾下,之前我们最普通关于RecyclerView的使用:

  1. 定义布局文件,放置RecyclerView;
  2. 定义对应的item文件;
  3. 编写对应的Java Bean以及Adapter,其中Adapter中需要单独编写ViewHolder类,且此类需继承RecyclerView.ViewHolder。

大概简单来讲就是以上三个步骤,那么我们根据以上三步骤并结合当前Data Binding去一步步学习掌握如何二者结合使用。

Step 1: 定义布局文件

这里需要注意以下几点:

  • 引入所需Java Bean以及我们的ObservableArrayList;

  • 通过app:data属性将我们的List传递到RecyclerView中。(注意使用app:data需要导入命名空间,并且RecyclerView本身并不提供setData的api,所以我们只能造一个。

上面说到,由于RecyclerView本身并不提供setData方式,所以我们需要自己造一个,那么有的小伙伴就会问了,我之前没使用Data Binding的时候,也不需要setData呀。其实这个东西大家可以简单理解为,它就是一个桥接的作用,将传递过来的数据与RecyclerView绑定,也就是真正让RecyclerView拿到传递的数据。 (当然,关于这块如果有更好更通俗的解释,欢迎拍砖~)

定义桥接类如下:

package com.hlq.databindingdemo.util;import android.databinding.BindingAdapter;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;import com.hlq.databindingdemo.adapter.ShowLoveHistoryAdapter;
import com.hlq.databindingdemo.bean.LoveBean;import java.util.List;/*** author : HLQ* e-mail : 925954424@qq.com* time   : 2018/02/24* desc   : 桥接ReccyclerView与Data Binding* version: 1.0*/
public class BindUtils {@BindingAdapter("data")public static void setShowLoveHistoryData(RecyclerView recyclerView,List<LoveBean> loveList) {recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));recyclerView.setAdapter(new ShowLoveHistoryAdapter(recyclerView.getContext(), loveList));}}

而我们放置RecyclerView布局如下:

<?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.hlq.databindingdemo.bean.LoveBean" /><import type="android.databinding.ObservableArrayList" /><variable
            name="loveList"type="ObservableArrayList&lt;LoveBean>" /></data><LinearLayout
        android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.hlq.databindingdemo.activity.RecyclerViewActivity"><android.support.v7.widget.RecyclerView
            android:id="@+id/showLove"android:layout_width="match_parent"android:layout_height="match_parent"app:data="@{loveList}" /></LinearLayout>
</layout>

Step 2: 定义对应的item文件

这里我们简单思考下:

既然是Adapter形式,那么传递到Item中当然是一个实体类形式,我们只需要将每次遍历得到的实体依次赋给item所需内容即可。

如演示图所示,这里为了方便就不单独定义实体类了,直接使用原有的,如下:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><data><variable
            name="love"type="com.hlq.databindingdemo.bean.LoveBean" /></data><RelativeLayout
        android:layout_width="match_parent"android:layout_height="wrap_content"><ImageView
            android:id="@+id/icon"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="15dp"android:background="@drawable/ic_launcher_round" /><TextView
            style="@style/contentStyle"android:layout_centerVertical="true"android:layout_marginTop="15dp"android:layout_toRightOf="@id/icon"android:text="@{love.youSelf}"tools:text="姓名" /><View
            android:layout_width="match_parent"android:layout_height="1dp"android:layout_below="@id/icon"android:background="#fff" /></RelativeLayout>
</layout>

item效果如下:

Step 3: 编写Adapter

package com.hlq.databindingdemo.adapter;import android.content.Context;
import android.databinding.DataBindingUtil;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.ViewGroup;import com.hlq.databindingdemo.R;
import com.hlq.databindingdemo.bean.LoveBean;
import com.hlq.databindingdemo.databinding.ItemLoveHistoryShowBinding;
import com.hlq.databindingdemo.holder.ShowLoveHistoryHolder;import java.util.List;/*** author : HLQ* e-mail : 925954424@qq.com* time   : 2018/02/24* desc   : RecyclerView与DataBinding使用* version: 1.0*/
public class ShowLoveHistoryAdapter extends RecyclerView.Adapter<ShowLoveHistoryHolder> {private Context mContext;private List<LoveBean> mLoveList;public ShowLoveHistoryAdapter(Context mContext, List<LoveBean> mLoveList) {this.mContext = mContext;this.mLoveList = mLoveList;}@Overridepublic ShowLoveHistoryHolder onCreateViewHolder(ViewGroup parent, int viewType) {ItemLoveHistoryShowBinding binding = DataBindingUtil.inflate(LayoutInflater.from(mContext),R.layout.item_love_history_show,parent, false);return new ShowLoveHistoryHolder(binding);}@Overridepublic void onBindViewHolder(ShowLoveHistoryHolder holder, int position) {holder.getBinding().setLove(mLoveList.get(position));// 立即刷新界面,防止列表更新不及时,导致数据错乱holder.getBinding().executePendingBindings();}@Overridepublic int getItemCount() {return mLoveList == null ? 0 : mLoveList.size();}}

这里为了方便,单独将ViewHolder抽取出来。

package com.hlq.databindingdemo.holder;import android.support.v7.widget.RecyclerView;import com.hlq.databindingdemo.databinding.ItemLoveHistoryShowBinding;/*** author : HLQ* e-mail : 925954424@qq.com* time   : 2018/02/24* desc   : RecyclerView 所需Holder* version: 1.0*/
public class ShowLoveHistoryHolder extends RecyclerView.ViewHolder {private ItemLoveHistoryShowBinding binding;public ShowLoveHistoryHolder(ItemLoveHistoryShowBinding binding) {super(binding.getRoot());this.binding = binding;}public ItemLoveHistoryShowBinding getBinding() {return binding;}public void setBinding(ItemLoveHistoryShowBinding binding) {this.binding = binding;}}

Step 4: 初始化

package com.hlq.databindingdemo.activity;import android.databinding.DataBindingUtil;
import android.databinding.ObservableArrayList;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;import com.hlq.databindingdemo.R;
import com.hlq.databindingdemo.bean.LoveBean;
import com.hlq.databindingdemo.databinding.ActivityRecyclerViewBinding;/*** author : HLQ* e-mail : 925954424@qq.com* time   : 2018/02/23* desc   : RecyclerView与DataBinding使用* version: 1.0*/
public class RecyclerViewActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ActivityRecyclerViewBinding binding =DataBindingUtil.setContentView(this, R.layout.activity_recycler_view);ObservableArrayList<LoveBean> loveList = new ObservableArrayList<>();for (int i = 0; i < 30; i++) {loveList.add(new LoveBean("youSelf" + i, "mySelf" + i, true));}binding.setLoveList(loveList);}
}

嗯,小手一点,运行一波,走起~

七、老方式设置RecyclerView点击事件

来来来,Come on,我们一起回顾下当年如何简单有效实现RecyclerView并为其添加点击事件:

  • Activity中摆放好RecyclerView;

  • 初始化,编写item以及对于Adapter、ViewHolder;

  • 当然,不要忘记在adapter中设置事件,Activity中回调。

那么基于以上路子,我们一块快速简单有效的撸一波有关结合Data Binding的用法吧~

Step 1:摆放RecyclerView

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><LinearLayout
        android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".activity.NormalRecyclerViewActivity"><TextView
            style="@style/contentStyle"android:text="换种姿势玩转RecyclerView" /><android.support.v7.widget.RecyclerView
            android:id="@+id/showList"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>
</layout>

Step 2:摆放Item_layout

这里需要注意,因为我们是结合Data Binding,而真正落实到Item时,仅仅是一个Model,也就是我们最终的实体类。
So,在此,我们需要将我们的Model传递进去。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><data><variable
            name="user"type="com.hlq.databindingdemo.bean.UserBean" /></data><LinearLayout
        android:id="@+id/parent_list"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextView
            android:id="@+id/item_list"style="@style/contentStyle"android:text="@{user.userName}"tools:text="item测试数据" /><View
            android:layout_width="match_parent"android:layout_height="2dp"android:background="#fff" /></LinearLayout>
</layout>

Step 3:编写Adapter

这里简单总结下,看看我们的Adapter中需要落实些什么鬼~!

  • 继承RecyclerView.Adapter,实现方法添加ViewHolder并继承RecyclerView.ViewHolder,而我们这次的Holder只需要Binding即可;

  • 传递Model,刷新RecyclerView;

  • 设置interface onItemClickListener;

嗯,基于以上三点,开始撸本次代码:

package com.hlq.databindingdemo.adapter;import android.content.Context;
import android.databinding.DataBindingUtil;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import com.hlq.databindingdemo.R;
import com.hlq.databindingdemo.bean.UserBean;
import com.hlq.databindingdemo.databinding.ItemShowListBinding;import java.util.List;/*** author : HLQ* e-mail : 925954424@qq.com* time   : 2018/05/09* desc   :* version: 1.0*/
public class ShowListAdapter extends RecyclerView.Adapter<ShowListAdapter.ViewHolder> {private Context mContext;private List<UserBean> mUserBeanList;private onItemClickListener mOnItemClickListener;private ItemShowListBinding mListBinding;public ShowListAdapter(Context context, List<UserBean> userBeanList) {this.mContext = context;this.mUserBeanList = userBeanList;}@Overridepublic ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {mListBinding = DataBindingUtil.inflate(LayoutInflater.from(mContext), R.layout.item_show_list, parent, false);return new ViewHolder(mListBinding);}@Overridepublic void onBindViewHolder(ViewHolder holder, final int position) {// 传递Modelholder.mListBinding.setUser(mUserBeanList.get(position));// 刷新RecyclerViewholder.mListBinding.executePendingBindings();// 设置事件 只需要传递当前item所需Model(Java Bean)即可if (mOnItemClickListener != null) {holder.mListBinding.parentList.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mOnItemClickListener.onItemClickListener(mUserBeanList.get(position));}});}}@Overridepublic int getItemCount() {return mUserBeanList.size();}class ViewHolder extends RecyclerView.ViewHolder {private ItemShowListBinding mListBinding;public ViewHolder(ItemShowListBinding listBinding) {super(listBinding.getRoot());this.mListBinding = listBinding;}}public void setOnItemClickListener(onItemClickListener onItemClickListener) {this.mOnItemClickListener = onItemClickListener;}public interface onItemClickListener {void onItemClickListener(UserBean userBean);}}

Step 4:初始化RecyclerView、数据以及设置事件处理

    private ActivityNormalRecyclerViewBinding mNormalBinding;private ShowListAdapter mShowListAdapter;private List<UserBean> mShowList;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mNormalBinding = DataBindingUtil.setContentView(this, R.layout.activity_normal_recycler_view);initData();initRecyclerViewSetting();}private void initData() {mShowList = new ArrayList<>();for (int i = 0; i < 30; i++) {mShowList.add(new UserBean("贺大大" + i));}}private void initRecyclerViewSetting() {mNormalBinding.showList.setLayoutManager(new LinearLayoutManager(this));mShowListAdapter = new ShowListAdapter(this, mShowList);mShowListAdapter.setOnItemClickListener(new ShowListAdapter.onItemClickListener() {@Overridepublic void onItemClickListener(UserBean userBean) {Toast.makeText(NormalRecyclerViewActivity.this, "点击了:" + userBean.getUserName(), Toast.LENGTH_SHORT).show();}});mNormalBinding.showList.setAdapter(mShowListAdapter);}

Step 5:运行一波,查看效果

嗯,简单的玩完了,下面基于第六小节实现RecyclerView点击~

八、来个装B的方式设置RecyclerView点击事件

既然本小节基于第六小节实现item点击,那么多余的部分LZ这里不再叙述,这里着重讲几点思路:

  • 由于我们的Adapter被单独抽取到BindUtil中进行初始化,那么对应的,我们也得在BindUtil初始化Adapter为其设置事件并进行后续处理;

  • 而对应的Adapter则主要在Bind数据时,单独为Icon设置点击事件,其它暂时不需要改动。

当然为了便于接收者处理,这里我们的事件直接传递Model,Adapter关键代码如下:

    @Overridepublic void onBindViewHolder(ShowLoveHistoryHolder holder, final int position) {holder.getBinding().setLove(mLoveList.get(position));// 立即刷新界面,防止列表更新不及时,导致数据错乱holder.getBinding().executePendingBindings();// 设置事件if (mOnItemClickListener != null) {holder.getBinding().icon.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mOnItemClickListener.OnItemClickListener(mLoveList.get(position));}});}}public void setOnItemClickListener(OnItemClickListener onItemClickListener) {this.mOnItemClickListener = onItemClickListener;}public interface OnItemClickListener {void OnItemClickListener(LoveBean loveBean);}

而对应的BindUtils中则只需要设置事件实例以及处理事件即可:

    @BindingAdapter("data")public static void setShowLoveHistoryData(final RecyclerView recyclerView,List<LoveBean> loveList) {recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));ShowLoveHistoryAdapter adapter = new ShowLoveHistoryAdapter(recyclerView.getContext(), loveList);adapter.setOnItemClickListener(new ShowLoveHistoryAdapter.OnItemClickListener() {@Overridepublic void OnItemClickListener(LoveBean loveBean) {Toast.makeText(recyclerView.getContext(), "点击了:" + loveBean.getYouSelf(), Toast.LENGTH_SHORT).show();}});recyclerView.setAdapter(adapter);}

基于第六小节修改完毕,运行走一波~

九、当Data Binding遇到ImageView

在我们的上面有关RecyclerView时,大家注意到一个@BindingAdapter(“data”)么?

这个东西是什么?

简单可以理解为:

@BindingAdapter()类似一个桥梁,主要负责数据到Data Binding层,同样,牛掰的地方也在于,可以为你想使用的控件硬生生加个特异功能~

好比我们的RecyclerView原本没有接收数据的属性,但是,薇薇改动后,就这么神器的有了~~~

同理,依照上面如何为RecyclerView添加Data,下面先来撸一个有关ImageView的Util:

package com.hlq.databindingdemo.util;import android.databinding.BindingAdapter;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;import com.bumptech.glide.Glide;/*** author : HLQ* e-mail : 925954424@qq.com* time   : 2018/05/16* desc   : Fuck Code Fuck Fuck Fuck* version: 1.0*/
public class ImageUtils {@BindingAdapter("imageResource")public static void setImageResource(ImageView imageView,int imgID) {imageView.setImageResource(imgID);}@BindingAdapter("imageDrawable")public static void setImageDrawable(ImageView imageView,Drawable imgDrawable) {imageView.setImageDrawable(imgDrawable);}@BindingAdapter({"defaultImg", "loadingImg", "errorImg"})public static void setImageForGlide(ImageView imageView,Drawable defaultImg,String imageAddress,Drawable errorImg) {Glide.with(imageView.getContext()).load(imageAddress).error(errorImg).placeholder(defaultImg).into(imageView);}}

布局里面就很easy咯(不过这里要注意,调用者顺序以及类型需要统一,不然真的就GG了~)

<?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="image"type="com.hlq.databindingdemo.bean.ImageBean" /></data><LinearLayout
        android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"tools:context=".activity.ImageViewActivity"><ImageView
            android:layout_width="80dp"android:layout_height="80dp"app:imageResource="@{image.imageResID}" /><ImageView
            android:layout_width="80dp"android:layout_height="80dp"android:layout_marginTop="15dp"app:imageDrawable="@{@drawable/hlq_gzh}" /><ImageView
            android:layout_width="80dp"android:layout_height="80dp"android:layout_marginTop="15dp"app:defaultImg="@{@drawable/hlq_gzh}"app:errorImg="@{@drawable/ic_launcher_round}"app:loadingImg="@{image.imgUrl}" /></LinearLayout>
</layout>

而对应Activity中则很easy,初始化即可:

mImageBinding = DataBindingUtil.setContentView(this, R.layout.activity_image_view);
ImageBean imageBean = new ImageBean();
imageBean.imageResID = R.drawable.ic_launcher_round;
imageBean.imgUrl = "http://d.hiphotos.baidu.com/image/pic/item/6159252dd42a2834171827b357b5c9ea14cebfcf.jpg";
mImageBinding.setImage(imageBean);

查看效果:

十、十全十美,进阶收宫,来个注解完美告白

之前我们也多多少少使用了几个项目中常用的注解,而本文最后,拓展几个可能会用到的注解,来一个进阶篇完美谢幕~

先来俩个恶搞薇薇的示例:

<?xml version="1.0" encoding="utf-8"?>
<layout><data><variable
            name="vv"type="com.hlq.databindingdemo.bean.VVBean" /></data><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".activity.WordActivity"><TextView
            android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="15dp"android:background="@{vv.vHeartBg ? @color/c_yellow : @color/c_while}"android:gravity="center"android:padding="15dp"android:text="VV内心颜色如同背景色"android:textColor="#000" /><TextView
            android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="15dp"android:background="@color/colorAccent"android:gravity="center"android:padding="15dp"android:text="@{vv.vDesc}"android:textColor="#000" /></LinearLayout>
</layout>

如下效果:

有的伙计说,你不怕薇薇怼你?

鸡排我大哥~~~啦啦啦

扯犊子完成,最后为大家提溜过来@BindingMethods以及@BindingMethod这俩个注解,玩完睡觉,正好想想高级篇如何实现,不知不觉,一周又要过去了。。。

@BindingMethods以及@BindingMethod,这俩货是一对儿,你别想着拆散人俩,小心AS不放过你,那么具体他们使用以及场景又有哪儿些呢?

  • @BindingMethods,通常作为类的一个注解,它的作用,便是为其类或者实例添加新的技能;

  • @BindingMethod:苦逼执行者,旗下有三个小弟,如下:

    • type:给谁增加技能;

    • attribute :别人怎么激活这个技能;

    • method:这个技能被激活后会什么大招,enmmm,比如虐薇薇,嗯,对,虐薇薇~

总扯犊子不干正事儿,小心被人说空有其表,华而不实:

首先,设置我们大招类:

package com.hlq.databindingdemo.weight;import android.content.Context;
import android.databinding.BindingMethod;
import android.databinding.BindingMethods;
import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatTextView;
import android.util.AttributeSet;
import android.widget.Toast;/*** author : HLQ* e-mail : 925954424@qq.com* time   : 2018/05/17* desc   : 大招类 主动激活 则将薇薇轰上天~!!!* version: 1.0*/
@BindingMethods(@BindingMethod(type = AppCompatTextView.class, // 目标attribute = "activation", // 激活方式method = "setActivation" // 激活后链接自动释放大招 )
)
public class VVBiuView extends AppCompatTextView {public VVBiuView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);}/*** 主动激活技能,将薇薇轰上天~** @param msg*/public void setActivation(String msg) {Toast.makeText(getContext(), msg, Toast.LENGTH_SHORT).show();}}

大招蓄势待发,下面开始布置环境(LZ这里顽皮一波):

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"><data><variable
            name="vv"type="com.hlq.databindingdemo.bean.VVBean" /></data><LinearLayout
        android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".activity.WordActivity"><com.hlq.databindingdemo.weight.VVBiuView
            android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="15dp"android:background="@color/colorPrimary"android:padding="15dp"android:text="我是隐藏大招~"app:activation="@{vv.vDesc}"/></LinearLayout>
</layout>

有的伙伴说,哎那谁,你TMD的实体类哪儿去了?

MD,给你~!!!

package com.hlq.databindingdemo.bean;/*** author : HLQ* e-mail : 925954424@qq.com* time   : 2018/05/17* desc   : 薇薇是个二货~!!!* version: 1.0*/
public class VVBean {public boolean vHeartBg;public String vDesc;public VVBean(boolean vHeartBg, String vDesc) {this.vHeartBg = vHeartBg;this.vDesc = vDesc;}}

emmmm,最后,简单实例化一下:

mWordBind = DataBindingUtil.setContentView(this, R.layout.activity_word);
mWordBind.setVv(new VVBean(true, "程序猿,Oh,程序媛一枚,灵活的双手编织动人的世界~"));

enmm,冒着被薇薇打死的风险撸完了,看下效果~

LZ比比会儿

有时候,总觉得自己很努力,但是未曾发现,那些比你优秀的人同样在努力。

鸡排,对技术的严谨,对成果的执着,对LZ这样小白态度。。。等等,太多太多,心里真的很佩服~

前行之楷模~!!!

薇薇,一个超级超级超级努力、拼的漂亮妹子,努力程度,让我自愧不如。

。。。 。。。

身边大佬默默努力的例子太多太多。。。

最后让我们一起努力,也来个赶超鸡排大大,迎娶薇薇大佬(开玩笑,开玩笑~~~)~

GitHub查看地址

https://github.com/HLQ-Struggle/DataBindingDemo

个人公众号

欢迎关注个人公众号,不定期更新~

赞赏

觉得不错来个赞赏,老铁双击666~

Android Study 之 如何通过Data Binding提升撸码逼格(进阶篇)相关推荐

  1. RK3288 android7.1.2 android studio 用户空间通过spi ioctl读取flash ID(进阶篇五)

    准备工作: 1.搭建adbwireless 环境 参考:https://blog.csdn.net/Chhjnavy/article/details/97643584 https://blog.csd ...

  2. IDEA万能快捷键,你必须知道的17个实用技巧,提升撸码效率!

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 本文阅读时间大约5分钟. IDEA里有一个万能快捷键(alt enter),功能非常强大,同一 ...

  3. Android开发教程 - 使用Data Binding(二)集成与配置

    本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...

  4. android 高级项目,从零开始的Android新项目8 - Data Binding高级篇

    承接上篇,本篇继续讲解一些Data Binding更加进阶的内容,包括:列表绑定.自定义属性.双向绑定.表达式链.Lambda表达式.动画.Component注入(测试)等. 列表绑定 App中经常用 ...

  5. Data Binding 用户指南(Android)

    1. 介绍 这篇文章介绍了如何使用Data Binding库来写声明的layouts文件,并且用最少的代码来绑定你的app逻辑和layouts文件. Data Binding库不仅灵活而且广泛兼容- ...

  6. Android Data Binding 详细介绍与使用

    构建环境 首先,确保能使用Data Binding,需要下载最新的 Support repository.否则可能报错,如图: 在模块的build.gradle文件中添加dataBinding配置 a ...

  7. Android开发教程 - 使用Data Binding(七)使用BindingAdapter简化图片加载

    本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...

  8. Android Data Binding 入门

    Android Data Binding 入门 参考 http://www.cnblogs.com/lizebo/p/5474366.html 配置环境 build.gradle android {. ...

  9. 2021-12-30 解决Android启用了DataBinding 不会自动生成相对应的Binding Data Binding class not generated

    Data Binding class 不会自动生成,原因是因为layout里面没有设置Layout 标签 修改前: <?xml version="1.0" encoding= ...

最新文章

  1. matlab之矩阵基础应用
  2. Linux 系统内存分析
  3. python精通多长时间_学Python需要多久能学会?精通Python需要多长时间?
  4. Java——多线程学习
  5. EL函数以及自定义标签的应用
  6. 线段树||BZOJ1593: [Usaco2008 Feb]Hotel 旅馆||Luogu P2894 [USACO08FEB]酒店Hotel
  7. 【Python】any() all() 用法
  8. vue+vuex初入门
  9. 情景规划(Scenario planning) (转载)
  10. SI4463配置软件wds3
  11. 紫光华宇拼音输入法 6.x bug集
  12. dota2 自定义官方服务器,DOTA2官网更新:服务器扩容 首部官方漫画发布
  13. 大数据分析方法有哪几种?
  14. Vue脚手架的三种安装方式
  15. 给大家介绍六个不错的数据分析工具
  16. TDB和SPARQL
  17. Mysql基础篇(2)—— 单行函数和聚合函数
  18. python线性回归实例 x轴坐标相同_python深度学习-tensorflow实现一个线性回归的案例...
  19. 初入职场不得不掌握的6个好习惯
  20. 只有微信账号,我可以查询聊天记录吗?

热门文章

  1. html文字翻牌效果,css3翻牌效果
  2. 谷歌 浏览器 清空浏览器 会清空localStorage 吗 会清空什么
  3. 1. 什么是Xamarin
  4. VCS Coverage 手册笔记
  5. 一篇文章读懂Java类加载器
  6. Word5——同一行带题注的两张图片生成的图表目录在同一行的解决办法
  7. 网络安全专业术语英文缩写对照表
  8. API测试之Postman使用全指南(一)——如何创建GET/POST请求
  9. Merkle Patricia Tree 梅克尔帕特里夏树(MPT)规范(笔记)
  10. 【召集上海浦东新区羽毛球友】组织源深附近的进才北校、动宜动、曼云羽毛球QQ群、微信群活动