Android DataBinding 项目使用介绍(二)

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原理解析”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章