Android DataBinding 項目使用介紹(二)
上一節我們介紹了databinding基本用法,今天抽空寫下一些實際項目開發用到的.比如listview,include標籤,imageView綁定URL數據,等.
listview
在listview中我們經常使用viewHolder來實現複用view,減少內存耗用,但是數據多的時候我們使用過多的setText,很麻煩,在databinding中變得很簡單,一兩句代碼的事,先看下,adapter中item中的xml代碼.
adapter_item.xml
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
>
<data>
<import type="interest.yiyongbao.mvp.model.BillInfo"/>
<variable type="BillInfo" name="unReplayBill"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
android:gravity="center_vertical"
android:orientation="vertical">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bill_add_time"
android:textColor="@color/text_default_hint"
android:textSize="@dimen/auto_28px"/>
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/auto_10px"
android:text="@{unReplayBill.getAdd_time}"
android:textColor="@color/text_default_hint"
android:textSize="@dimen/auto_28px"
/>
</LinearLayout>
</LinearLayout>
</layout>
在最外層佈局根節點加入data標籤,表示數據區,在data中導入我們需要使用的類BillInfo.
下面對adapter進行一個小封裝:
public abstract class AdapterBindingImlp<T> extends BaseAdapter{
public List<T> mList;
private Context mContext;
public AdapterBindingImlp(Context context, List<T> list ) {
mList=list;
mContext=context;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewDataBinding binding=null;
if(convertView==null){
int layoutId=getItemLayout();
binding= DataBindingUtil.inflate(LayoutInflater.from(mContext), layoutId,parent,false);
convertView=binding.getRoot();
convertView.setTag(binding);
AutoUtils.autoSize(convertView);
}else {
binding = (ViewDataBinding) convertView.getTag();
}
initView(binding,position);
return convertView;
}
public abstract int getItemLayout();
public abstract void initView(ViewDataBinding binding, int position);
}
- convertView是顯示在UI上item的root view,在這裏看出沒有使用viewholder去生成view,因爲viewdatabinding本身就是一個由adapter_item.xml演變的view對象,(不過注意這裏adapter_item.xml,在databingding中已經進行了一個預處理,自動生成AdapterItemBinding類,而viewdatabinding正是它父類,如果需要去獲取佈局中的view,只需要對它進行轉換即可((AdapterItembinding)viewdatabinding).time即可獲取xml中id爲time的控件)
- 在getview中判斷convertView是否爲空,爲空則對該item進行初始化,寫法跟我們以前基本一樣,convertView=binding.getRoot()獲取viewDataBinding最外層的跟佈局,也就是我們通常的viewholder對應的佈局view
- 最後setTag綁定這個viewdatabinding
看下Baseadapter實現類
public class URepayBillAdapter extends AdapterBindingImlp<BillInfo> {
public URepayBillAdapter(Context context, List<BillInfo> list) {
super(context, list);
}
@Override
public int getItemLayout() {
return R.layout.item_adapter_urepaybill;
}
@Override
public void initView(ViewDataBinding binding, int position) {
binding.setVariable(BR.unReplayBill,mList.get(position));
}
}
- URepayBillAdapter中只需要一句setVaeiable就可以對數據進行綁定
- 參數一的BR類是在一個類似R類,裏面存放的是在xml中導入使用類的命名演變的標識,當數據進行綁定或者改變時,都是通過BR中這些標識去通知更新.
- 參數二,也就是我們所說的數據
include標籤
在xml中使用include標籤的時候,我們需要綁定include佈局中的數據怎辦?
先看下activity佈局文件:activity_main.xml
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<data>
<import type="interest.yiyongbao.mvp.model.UserInfo"/>
<variable type="UserInfo" name="titleInfo"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background"
android:orientation="vertical">
<include
android:id="@+id/titleLayout"
app:UserInfo="@{titleInfo}"
layout="@layout/title_layout"/>
</LinearLayout>
</layout>
- activity_main.xml中包含着子佈局title_lyout.xml,由於子佈局是另一個xml,如何才能去共享主佈局的數據?其實很簡單,只需要把activity_main.xml中的數據按照databinding方式進行傳遞到include中,在include總必須保證有這個對象的定義.
- 添加命名空間xmlns:app=”http://schemas.android.com/apk/res-auto” 這個命名是我們隨意的
- app:UserInfo=”@{titleInfo}”傳入需要的數據titleInfo
include佈局title_Layout:
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
>
<data>
<import type="interest.yiyongbao.mvp.model.UserInfo"/>
<variable type="UserInfo" name="titleInfo"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<RelativeLayout
android:id="@+id/titleLayout"
android:layout_width="match_parent"
android:layout_height="@dimen/titleLayout_110px"
android:background="@color/title_bg">
<TextView
android:id="@+id/title_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{titleInfo.name}"
android:textColor="@color/white"
android:layout_centerInParent="true"
android:textSize="@dimen/auto_35px"/>
</LineatLayout>
</layout>
- title_layout.xml中也需要有傳遞對象的綁定
這裏要拓展一個內容,關於如何java代碼中動態獲取這個include中控件呢?
我們看下acitivty代碼:
@Override
public void onCreate(Bundle arg0) {
super.onCreate(arg0);
ActivityMainBinding mBinding= DataBindingUtil.setContentView(this, R.layout.activity_main);
TitleLayoutBinding titleLayoutBinding=mBinding.titleLayout;
titleLayoutBinding.titleTv.setText("title");
}
可以看出通過給include設置id—->titleLayout,在include只要使用了databinding標籤,也會生成一個TitleLayoutBinding,所以只要通過id,就可以直接獲取這個TitleLayoutBinding.
ImageView綁定圖片Url
imageview可以在xml中設置圖片的url?yes
xml:
<?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="interest.yiyongbao.mvp.model.UserInfo"/>
<variable type="UserInfo" name="titleInfo"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:textSize="@dimen/auto_30px"
android:textColor="@color/text_default"
android:id="@+id/title_tv" />
<ImageView
android:layout_width="match_parent"
android:layout_height="300px"
android:src="@drawable/loading_pic2"
app:url="@{titleInfo.image}"
android:layout_gravity="center_horizontal"
android:scaleType="centerCrop"
android:id="@+id/imageView" />
</LinearLayout>
工具類:
/**
* Created by Administrator on 2017/2/25.
* 該工具是databinding自定義屬性,會自動需要該註解設置圖片,不需要調用
*/
public class BindImageUtil {
@BindingAdapter("url")
public static void setImgeViewSrc(ImageView view, int resId) {
view.setImageResource(resId);
}
@BindingAdapter("url")
public static void setImgeViewSrc(ImageView view, String url) {
Glide.with(view.getContext()).load(ParseUtil.BASE_IMG_URL+url).placeholder(view.getContext().getResources().getDrawable(R.drawable.loading_pic2)).crossFade().into(view);
}
}
這個工具類不需要我們去調用,根據databinding配置好,內部自動會調用,完成這個方法.
- 定義命名空間app,可以隨意定義
- 設置imageview —> app:url=”@{titleInfo.image}” –>titleInfo.image就是我們的圖片url,
- 命名控件的命名app:url必須與@BindingAdapter(“url”)一一對應,
- 編寫註解url的方法,方法名可以自由定義,方法參數必須對應有該imageview,與url.
<下面介紹下一篇不錯的databinding原理解析的博客databinding原理解析”