前段時間,完結了一篇Data Binding前篇,地址如下:
如何通過Data Binding提升擼碼逼格(基礎篇)
而今,我們一起來學習下,有關Data Binding進階用法。
發車了,來來來一、notifyPropertyChanged方式更新指定數據首先,來簡單介紹下Observable:
先來一個小例子:
那麼針對這個需求,我們使用Observable即可分分鐘搞定。這裡,大家可以簡單理解為,這個就是負責數據更新~
下面來個Demo試試:
Step 1: 實體類繼承BaseObservable
package com.hlq.databindingdemo.bean;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
import com.hlq.databindingdemo.BR;
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;
}
@Bindable
public String getClassNo() {
return classNo;
}
public void setClassNo(String classNo) {
this.classNo = classNo;
}
@Bindable
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
@Bindable
public 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");
@Override
protected 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當中也只是簡單的調用事件以及賦值,簡單貼出部分代碼:
<EditText
style="@style/titleStyle"
android:onTextChanged="@{presenter.onTextChanged}" />
<TextView
style="@style/contentStyle"
android:text="展示數據更新-notifyPropertyChanged" />
<TextView
style="@style/titleStyle"
android:text="@{classX.classNo}" />
<TextView
style="@style/titleStyle"
android:text="@{classX.classNum}" />
<TextView
style="@style/titleStyle"
android:text="@{classX.className}" />
先來看一波效果:
有的小夥伴說了,這TMD太麻煩了,我實體類屬性欄位有很多腫麼辦?一個個添加嗎?
當然不。身為程序猿猿,能偷懶,當然不傻傻幹。瞧好吧您吶~
二、notifyChange方式更新全部數據基於上節,本次單獨定義一個實體類,用於展示更新全部數據。
package com.hlq.databindingdemo.bean;
import android.databinding.BaseObservable;
import android.databinding.ObservableBoolean;
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再囉嗦一句,倆者區別在於:
當然,Data Binding的神奇之處還有很多,比如,它為我們提供了對應的一系列ObservableField,那麼,下面,讓我們一起去看看吧~
三、ObservableField Study簡單說一下ObservableField是什麼鬼:
首先,ObservableField是歸屬於Observable旗下,作用就是為了簡化操作,避免你寫多餘的get/set,當然嘍,優點並不止這些;
其次,Observable旗下包含了很多類似ObservableField的傢伙,例如:ObservableInt、ObservableBoolean等。
如何使用呢?你怎麼使用String、int等,就怎麼使用這個。說白了,就是一個配套的傢伙。
那麼接下來,簡單搞倆個Demo熟悉下使用:
Example One:先來個ObservableField練練手
Step 1: 定義實體類
import android.databinding.ObservableField;
public class MissBean {
public final ObservableField<String> missWho = new ObservableField<>();
public final ObservableField<String> missYou = new ObservableField<>();
}
Step 2: 布局引用
引入命名空間。
<data>
<variable
name="missBean"
type="com.hlq.databindingdemo.bean.MissBean" />
</data>
設置對應值。
<TextView
style="@style/titleStyle"
android:text="@{missBean.missWho}" />
<TextView
style="@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;
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>
<variable
name="filedBean"
type="com.hlq.databindingdemo.bean.ObservableFieldBean" />
</data>
接下來賦值:
<TextView
style="@style/contentStyle"
android:text="Observable Field" />
<TextView
style="@style/titleStyle"
android:text="@{filedBean.filedName}" />
<TextView
style="@style/titleStyle"
android:text='@{"年紀:"+filedBean.fileAge}' />
<TextView
style="@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 StudyStep 1: 引入命名空間,聲明類型
<data>
<import type="android.databinding.ObservableArrayList" />
<variable
name="loveList"
type="ObservableArrayList<String>" />
</data>
這裡需要注意,指定type時,ObservableArrayList類型裡面不能包含<,而是通過 < ; 代替。
Step 2: 賦值
<TextView
style="@style/contentStyle"
android:text="ObservableArrayList Study" />
<TextView
style="@style/titleStyle"
android:text="@{loveList.get(0)}" />
<TextView
style="@style/titleStyle"
android:text="@{loveList.get(1)}" />
是不是很Easy,直接通過下標去訪問即可。
Step 3: 查看演示效果
五、ObservableMap StudyStep 1: 布局添加引用
<data>
<import type="android.databinding.ObservableMap" />
<variable
name="loveMap"
type="ObservableMap<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的使用:
定義布局文件,放置RecyclerView;
定義對應的item文件;
編寫對應的Java Bean以及Adapter,其中Adapter中需要單獨編寫ViewHolder類,且此類需繼承RecyclerView.ViewHolder。
大概簡單來講就是以上三個步驟,那麼我們根據以上三步驟並結合當前Data Binding去一步步學習掌握如何二者結合使用。
Step 1: 定義布局文件
這裡需要注意以下幾點:
上面說到,由於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;
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<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;
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;
}
@Override
public 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);
}
@Override
public void onBindViewHolder(ShowLoveHistoryHolder holder, int position) {
holder.getBinding().setLove(mLoveList.get(position));
holder.getBinding().executePendingBindings();
}
@Override
public 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;
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;
public class RecyclerViewActivity extends AppCompatActivity {
@Override
protected 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中需要落實些什麼鬼~!
嗯,基於以上三點,開始擼本次代碼:
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;
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;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
mListBinding = DataBindingUtil.inflate(LayoutInflater.from(mContext), R.layout.item_show_list, parent, false);
return new ViewHolder(mListBinding);
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.mListBinding.setUser(mUserBeanList.get(position));
holder.mListBinding.executePendingBindings();
if (mOnItemClickListener != null) {
holder.mListBinding.parentList.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mOnItemClickListener.onItemClickListener(mUserBeanList.get(position));
}
});
}
}
@Override
public 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;
@Override
protected 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() {
@Override
public 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這裡不再敘述,這裡著重講幾點思路:
當然為了便於接收者處理,這裡我們的事件直接傳遞Model,Adapter關鍵代碼如下:
@Override
public 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() {
@Override
public 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() {
@Override
public 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;
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;
@BindingMethods(
@BindingMethod(
type = AppCompatTextView.class,
attribute = "activation",
method = "setActivation"
)
)
public class VVBiuView extends AppCompatTextView {
public VVBiuView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
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;
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