DataBindingAdapter在项目中实战

对于DataBinding不熟悉的小伙伴可以去官网了解下使用教程: https://developer.android.google.cn/topic/libraries/data-binding

这里就不详细介绍DataBinding了,接下来我列举下在项目中常用的结合不同控件的使用情况,当然还有很多控件没有使用到,在这里就不一一列举了,后期会持续更新上来。

1. ImageView

@BindingAdapter(value = {"url"})
public static void url(ImageView imageView,String url) {
    //此处可以使用图片请求框架, 例如
    Picasso.get().load(url).error(R.drawable.ic_empty).into(imageView);

ImageView中使用BindingAdapter中的value值\color{#0000FF}{url},如何使用,代码如下:

app:url ="@{网络图片地址}"

图片层级设置

@BindingAdapter(value = {"levels"})
public static void setLevel(ImageView imageView,int levels) {
    imageView.setImageLevel(levels);

矢量图颜色修改

@BindingAdapter(value = {"tints"})
public static void setTints(ImageView imageView, @ColorInt int color) {
    imageView.getDrawable().setTint(color);

GIF图片加载

@BindingAdapter({"asset"})
public static void setImageAssent(GifImageView view, String assent) {
    try {
        GifDrawable gifFromAssets = new GifDrawable(view.getContext().getAssets(), assent);
        view.setImageDrawable(gifFromAssets);
    } catch (IOException e) {
        e.printStackTrace();

2. RadioGroup

    <RadioGroup
        android:orientation="horizontal"
        android:onCheckedChanged="@{(group, buttonId) -> vm.setGroupSpeedIndex(group.indexOfChild(group.findViewById(buttonId)))}"
        <androidx.appcompat.widget.AppCompatRadioButton
            android:checked="@{vm.parameterBean.speedValue==1}"
            android:text="低"/>
        <androidx.appcompat.widget.AppCompatRadioButton
            android:checked="@{vm.parameterBean.speedValue==2}"
            android:text="中"/>
        <androidx.appcompat.widget.AppCompatRadioButton
            android:checked="@{vm.parameterBean.speedValue==3}"
            android:text="高"/>
    </RadioGroup>

viewModel中的方法

    public void setGroupSpeedIndex(int index) {
          parameterBean.getSpeedValue().set(index+1);

获取的值使用双向绑定BaseObservable

public class ConfigParameterBean extends BaseObservable {
private ObservableField<Integer>  speedValue;  
public ConfigParameterBean(){
    speedValue  = new ObservableField<>(2);
public ObservableField<Integer> getSpeedValue() {
    return speedValue;

3. SeekBar 同上RadioGroup的用法

    <androidx.appcompat.widget.AppCompatSeekBar
        android:progress="@={vm.parameterBean.downUpValue}"

4. RecycleView

\color{#0000FF}{app:decoration}属性是获取分割线,recycleView中使用如下:

    <androidx.recyclerview.widget.RecyclerView
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            app:decoration="@{vm.getItemDecoration()}"
            app:adapter="@{vm.adapter}"

bindingAdapter中的使用:

@BindingAdapter(value = {"decoration"})
public static void setDecoration(RecyclerView recyclerView, RecyclerView.ItemDecoration itemDecoration) {
    recyclerView.addItemDecoration(itemDecoration);

ViewModel中的使用:

public RecyclerView.ItemDecoration getItemDecoration(){
    DividerItemDecoration itemDecoration = new DividerItemDecoration(getApplication(), DividerItemDecoration.VERTICAL);
    itemDecoration.setDrawable(Objects.requireNonNull(ContextCompat.getDrawable(getApplication(), R.drawable.bg_trans_item_height_10)));
    return itemDecoration;
//适配器
public MapAdapter getAdapter(){
    return adapter;

5. SwipeRefreshLayout

SwipeRefreshLayoutd控件的使用,\color{#0000FF}{app:colorResIds}加载颜色的设置,如下:

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        app:colorResIds="@{vm.getColorResId()}"
        app:refreshing="@{vm.isRefreshing}"
        app:onRefreshListener="@{vm::onRefresh}"
    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

bindingAdapter中的使用:

@BindingAdapter(value = {"colorResIds"})
public static void setColorResIds(SwipeRefreshLayout refreshLayout,@ColorRes int... colorInt) {
    refreshLayout.setColorSchemeResources(colorInt);

ViewModel中的使用:

public @ColorRes int[] getColorResId(){
    return new int[]{R.color.purple_200,R.color.purple_500,R.color.purple_700,R.color.teal_200,R.color.teal_700};
public MutableLiveData<Boolean> getIsRefreshing() {
    return isRefreshing;

6. SmartRefreshLayout

SmartRefreshLayout的使用(目前使用2.0.3版本)

    <com.scwang.smart.refresh.layout.SmartRefreshLayout
        app:hasMore="@{vm.hasMore}"
        app:refreshing="@{vm.refreshing}"
        app:moreLoading="@{vm.moreLoading}"
        app:onRefreshListener="@{()->vm.onRefresh()}"
        app:onLoadMoreListener="@{()->vm.onLoadMore()}"
        <androidx.recyclerview.widget.RecyclerView
    </com.scwang.smart.refresh.layout.SmartRefreshLayout>

bindingAdapter中的使用:

@BindingAdapter(value = {"refreshing","moreLoading","hasMore"},requireAll = false)
public static void bindSmartRefreshLayout(SmartRefreshLayout smartLayout, Boolean refreshing, Boolean moreLoading, Boolean hasMore) {
    if (!refreshing) smartLayout.finishRefresh();
    if (!hasMore) smartLayout.finishLoadMoreWithNoMoreData();
    if (!moreLoading) smartLayout.finishLoadMore();
@BindingAdapter(value = {"autoRefresh"})
public static void bindSmartRefreshLayout(SmartRefreshLayout smartLayout,boolean autoRefresh) {
    if (autoRefresh) smartLayout.autoRefresh();
@BindingAdapter(value = {"onRefreshListener","onLoadMoreListener"},requireAll = false)
public static void bindSmartRefreshLayout(SmartRefreshLayout smartLayout, OnRefreshListener onRefreshListener, OnLoadMoreListener onLoadMoreListener) {
    smartLayout.setOnRefreshListener(onRefreshListener);
    smartLayout.setOnLoadMoreListener(onLoadMoreListener);
@BindingAdapter(value = {"refreshing"})
public static void bindSmartRefreshLayout(SwipeRefreshLayout swipeRefreshLayout, Boolean refreshing) {
    swipeRefreshLayout.setRefreshing(refreshing);

veiwModel中的使用:

  • 继承于BaseViewModelPage,实现\color{#FF0000}{onRefresh()、onLoadMore()} 方法;
  • 数据加载完成要记得调用\color{#FF0000}{onRefreshSuccess()、onRefreshError()}方法
  • autoRefresh()方法未使用,待验证,如果有问题可以告诉我。
  • @Override
    public void onRefresh() {
        super.onRefresh();
        requestData();//数据请求
    @Override
    public void onLoadMore() {
        super.onLoadMore();
        requestData();
    //大家可以根据自己的需求去处理数据加载逻辑
    private void requestData() {
        if (null != iViewListener) iViewListener.startLoading();
        //noinspection ConstantConditions
        requestManager.getMessages(getPage().getValue(), 20)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<MessagesBean>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                    @Override
                    public void onNext(@NonNull MessagesBean success) {
                        if (null != iViewListener)iViewListener.stopLoading();
                        if (null != success.getData() && success.getData().size() > 0) {
                            total = success.getTotalCount();
                            data.addAll(success.getData());
                        adapter.notifyDataSetChanged();
                        onRefreshSuccess();
                    @Override
                    public void onError(@NonNull Throwable e) {
                        if (null != iViewListener) iViewListener.stopLoading();
                        adapter.notifyDataSetChanged();
                        onRefreshError();
                    @Override
                    public void onComplete() {
    

    viewModel的基类代码较多,这里将源码贴出来

    public abstract class BaseViewModelPage<D> extends BaseModel {
    private final MutableLiveData<Integer> page = new MutableLiveData<>();       //页码
    private final MutableLiveData<Boolean> refreshing = new MutableLiveData<>(); //刷新
    private final MutableLiveData<Boolean> moreLoading = new MutableLiveData<>();//加载更多
    private final MutableLiveData<Boolean> hasMore = new MutableLiveData<>();    //是否全部加载
    private final MutableLiveData<Boolean> autoRefresh = new MutableLiveData<>();//自动刷新
    protected final List<D> data = new ArrayList<>();  //数据集合
    protected int total = 0;                           //数据总数
    public BaseViewModelPage(@NonNull Application application) {
        super(application);
        page.setValue(0);
        refreshing.setValue(true);
        moreLoading.setValue(true);
        hasMore.setValue(true);
        autoRefresh.setValue(false);
    @CallSuper
    public void onLoadMore() {
        page.setValue(page.getValue()==null?0: page.getValue()+1);
        if (refreshing.getValue())refreshing.setValue(false);
        if (!moreLoading.getValue())moreLoading.setValue(true);
    @CallSuper
    public void onRefresh() {
        page.setValue(0);
        refreshing.setValue(true);
        if (data.size()>0) data.clear();
        if (moreLoading.getValue()) moreLoading.setValue(false);
        if (!hasMore.getValue()) hasMore.setValue(true);
    @CallSuper
    public void autoRefresh() {
        autoRefresh.setValue(true);
    public MutableLiveData<Integer> getPage() {
        return page;
    public MutableLiveData<Boolean> getHasMore() {
        return hasMore;
    public MutableLiveData<Boolean> getRefreshing() {
        return refreshing;
    public MutableLiveData<Boolean> getMoreLoading() {
        return moreLoading;
    public MutableLiveData<Boolean> getAutoRefresh() {
        return autoRefresh;
    protected void onRefreshSuccess(){
        if (page.getValue() == 0) {
            if (refreshing.getValue()) refreshing.setValue(false);
        } else {
            if (data.size()>= total) {
                if (hasMore.getValue()) hasMore.setValue(false);
            } else {
                if (!hasMore.getValue()) hasMore.setValue(true);
            if (moreLoading.getValue())moreLoading.setValue(false);
    protected void onRefreshError() {
        if (page.getValue() == 0) {
            if (!refreshing.getValue()) refreshing.setValue(true);
        } else {
            if (data.size()>= total) {
                if (hasMore.getValue()) hasMore.setValue(false);
            } else {
                if (!hasMore.getValue()) hasMore.setValue(true);
            if (moreLoading.getValue())moreLoading.setValue(false);
    //重写父类的方法子类也需要调用时使用
    @CallSuper
    @Override
    public void onCleared() {