databinding 自定義view中的雙向綁定

需求場(chǎng)景 :
在viewmodel中需要改變一個(gè)自定義view的自定義屬性(比如 smartrefashlayout的下拉刷新去請(qǐng)求數(shù)據(jù),以及加載完成或者刷新完成關(guān)閉加載動(dòng)畫)

思路:
1.mvvmlight 提供的command 方式(只適合自定義view中存在暴露給外部監(jiān)聽的方式,或者自
己通過(guò)bindadapter監(jiān)聽某個(gè)狀態(tài)達(dá)到目的的場(chǎng)景,后面會(huì)講具體實(shí)現(xiàn))
command 的解決問(wèn)題的方式是利用了bindadapter 和 java8的函數(shù)式編程(當(dāng)然你用rxjava
也ok)。

2.通過(guò)bindadapter 和 InverseBindingAdapter (http://www.itdecent.cn/p/a05c9735f595)/(https://yq.aliyun.com/articles/615840

方式1 實(shí)現(xiàn)步驟:

 a. 定義command   (jdk8的函數(shù)接口)
   @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();};

 結(jié)果: 發(fā)現(xiàn)下拉刷新絲滑了,數(shù)據(jù)驅(qū)動(dòng),但是你會(huì)發(fā)現(xiàn)數(shù)據(jù)獲取成功后加載的動(dòng)畫并沒有關(guān)閉 so 方式二就需要出場(chǎng)救急了

方式二實(shí)現(xiàn)步驟

1. 下載smartrefashlayout 的源碼,使用導(dǎo)入module的方式引入項(xiàng)目(因?yàn)閷?duì)反向綁定的InverseBindingMethods使用的不多,接下來(lái)會(huì)研究,等第二篇)
  1. 增加view的自定義屬性 <attr name="refreshcomplete" format="boolean"/> 3. initview的時(shí)候獲取屬性并提供setter getter,
    refreshcomplete =
    ta.getBoolean(R.styleable.SmartRefreshLayout_refreshcomplete,false);

       public boolean getRefreshcomplete() {
         return refreshcomplete;
        }
         public void setRefreshcomplete(boolean refreshcomplete) {
         this.refreshcomplete = refreshcomplete;
         }
    
    1. 自己領(lǐng)會(huì)下,等后邊步驟看完就知道為嘛要這樣了
      @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. 定義 實(shí)體類,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);
}

}

注意規(guī)范,類的首字母必須大寫,書寫規(guī)范能避免很多大坑

  <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 中實(shí)例化
    public Testvo vo = new Testvo();
    activity 中setData

7.完成,再回頭看步驟4,有沒有明白呢?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 為什么不能安安靜靜的把每天要做的事情做好 難道你早已死了 只不過(guò)在茍延殘喘么 你想承認(rèn)這一點(diǎn)??? 我有點(diǎn)不敢相信...
    溫拿大沒拿大閱讀 206評(píng)論 0 0
  • 我只是想向你指出,自我犧牲是壓倒一切的情感,連淫欲和饑餓跟它相比都會(huì)顯得微不足道。它最大程度地使人格高尚化,誘惑人...
    西苑98閱讀 338評(píng)論 0 0
  • 日于晨升。忽見峰巔立于云霄之上。霧茫似海,裹之入懷。深入云雷,隱隱涌見數(shù)光。累之,忽金光耀蒼穹,沖破長(zhǎng)空,...
    水草花開閱讀 161評(píng)論 0 0
  • 零售—未來(lái)計(jì)劃 背景:在ces的基礎(chǔ)上 加上dell,惠普,dell新品,小米等幾個(gè)品牌的綜合抽離后整理。分析后c...
    TC_25fe閱讀 188評(píng)論 0 1

友情鏈接更多精彩內(nèi)容