美文网首页
databinding 自定义view中的双向绑定

databinding 自定义view中的双向绑定

作者: Lz_Docker | 来源:发表于2019-03-13 15:46 被阅读0次

    需求场景 :
    在viewmodel中需要改变一个自定义view的自定义属性(比如 smartrefashlayout的下拉刷新去请求数据,以及加载完成或者刷新完成关闭加载动画)

    思路:
    1.mvvmlight 提供的command 方式(只适合自定义view中存在暴露给外部监听的方式,或者自
    己通过bindadapter监听某个状态达到目的的场景,后面会讲具体实现)
    command 的解决问题的方式是利用了bindadapter 和 java8的函数式编程(当然你用rxjava
    也ok)。

    2.通过bindadapter 和 InverseBindingAdapter (https://www.jianshu.com/p/a05c9735f595)/(https://yq.aliyun.com/articles/615840

    方式1 实现步骤:

     a. 定义command   (jdk8的函数接口)
       @FunctionalInterface
      public interface ReplyCommand {
       void exectue();
     }
    
    b.BindingAdapter
    
         public class BindingAdapters {
         @BindingAdapter({"onRefreshCommand"})
         public static void setonRefreshCommand(SmartRefreshLayout smartRefreshLayout, final ReplyCommand onRefreshCommand) {
             smartRefreshLayout.setOnRefreshListener(new OnRefreshListener() {
                 @Override
                 public void onRefresh(RefreshLayout refreshLayout) {
                     onRefreshCommand.exectue();
                 }
             });
         }
    
         @BindingAdapter({"onloadmoreCommand"})
         public static void setonloadmoreCommand(SmartRefreshLayout smartRefreshLayout, final ReplyCommand onloadmoreCommand) {
             smartRefreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
                 @Override
                 public void onLoadMore(RefreshLayout refreshLayout) {
                     onloadmoreCommand.exectue();
                 }
             });
         }
    
         @BindingAdapter({"oncompleteCommand"})
         public static void setoncompleteCommand(SmartRefreshLayout smartRefreshLayout, final ReplyCommandParam oncompleteCommand) {
             oncompleteCommand.exectue(smartRefreshLayout);
         }
     }
    
    c. xml 中引用
    
     <com.scwang.smartrefresh.layout.SmartRefreshLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         bind:onRefreshCommand="@{viewModel.onrefreshCommand}"
         bind:onloadmoreCommand="@{viewModel.onloadmoreCommand}">
    
         <android.support.v7.widget.RecyclerView
             android:id="@+id/recycle"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             bind:itemView="@{viewModel.KnowitemBinding}"
             bind:items="@{viewModel.knowItems}"
             bind:layoutManager="@{LayoutManager.linear()}" />
    
     </com.scwang.smartrefresh.layout.SmartRefreshLayout>
    
     d.viewmodel 中使用
    
     public final ReplyCommand onrefreshCommand = ()->{ getKnowledgeHierarchyData();};
    
     public final ReplyCommand onloadmoreCommand = ()->{ getKnowledgeHierarchyData();};
    
     结果: 发现下拉刷新丝滑了,数据驱动,但是你会发现数据获取成功后加载的动画并没有关闭 so 方式二就需要出场救急了
    
    

    方式二实现步骤

    1. 下载smartrefashlayout 的源码,使用导入module的方式引入项目(因为对反向绑定的InverseBindingMethods使用的不多,接下来会研究,等第二篇)
    
    1. 增加view的自定义属性 <attr name="refreshcomplete" format="boolean"/> 3. initview的时候获取属性并提供setter getter,
      refreshcomplete =
      ta.getBoolean(R.styleable.SmartRefreshLayout_refreshcomplete,false);

         public boolean getRefreshcomplete() {
           return refreshcomplete;
          }
           public void setRefreshcomplete(boolean refreshcomplete) {
           this.refreshcomplete = refreshcomplete;
           }
      
      1. 自己领会下,等后边步骤看完就知道为嘛要这样了
        @BindingAdapter("refreshcompleteAttrChanged")
        public static void setRefreshcompleteAttrChanged(SmartRefreshLayout view, InverseBindingListener inverseBindingListener) {
        if (inverseBindingListener == null) {
        view.setListener(null);
        } else {
        view.setListener(inverseBindingListener::onChange);
        }
        }
        @BindingAdapter(value = "refreshcomplete")
        public static void setcomplete(SmartRefreshLayout view, boolean refreshcomplete) {
        view.setRefreshcomplete(refreshcomplete);
        if(refreshcomplete){
        view.finishRefresh();
        view.finishLoadMore();
        }
        }
        @InverseBindingAdapter(attribute = "refreshcomplete", event = "refreshcompleteAttrChanged")
        public static boolean getcomplete(SmartRefreshLayout view) {
        return view.getRefreshcomplete();
        }

      private OnValueChangedListener listener;

      public interface OnValueChangedListener {
      void onValueChanged();
      }

      public void setListener(OnValueChangedListener listener) {
      this.listener = listener;
      }

      1. 定义 实体类,xml中使用

      public class Testvo extends BaseObservable implements Serializable {

    public boolean complete;
    @Bindable
    public boolean getComplete() {
        return complete;
    }
    
    public void setComplete(boolean complete) {
        this.complete = complete;
        notifyPropertyChanged(BR.complete);
    }
    

    }

    注意规范,类的首字母必须大写,书写规范能避免很多大坑

      <variable
            name="data"
            type="com.docker.moduleplayer.vo.Testvo"/>
    
        <import type="com.docker.commonlibrary.bind.recycleviewbind.LayoutManager" />
    </data>
    
    <com.scwang.smartrefresh.layout.SmartRefreshLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    

        bind:refreshcomplete="@={data.complete}"
    

        bind:onRefreshCommand="@{viewModel.onrefreshCommand}"
        bind:onloadmoreCommand="@{viewModel.onloadmoreCommand}">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycle"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            bind:itemView="@{viewModel.KnowitemBinding}"
            bind:items="@{viewModel.knowItems}"
            bind:layoutManager="@{LayoutManager.linear()}" />
    
    </com.scwang.smartrefresh.layout.SmartRefreshLayout>
    
    1. viewmodel 中实例化
      public Testvo vo = new Testvo();
      activity 中setData

    7.完成,再回头看步骤4,有没有明白呢?

    相关文章

      网友评论

          本文标题:databinding 自定义view中的双向绑定

          本文链接:https://www.haomeiwen.com/subject/vfhtmqtx.html