DataBinding(一)基礎

1. 導入

在module的build.gradle中聲明

android {
    dataBinding {
        enabled true
    }
}

如果依賴庫中使用了DataBinding,則module也要使用DataBinding纔行。

Android Gradle Plugin 3.1.0 canary 6提供了另外一種新的DataBinding編譯器V2,具體啓用方式是:

// gradle.properties
android.databinding.enableV2=true

v1和v2互不兼容。相對於v1編譯器,v2編譯器具有以下特點:

  • 避免無關報錯。ViewBinding類是由Gradle插件負責生成的,而不是Java編譯器,所以不會像之前由於Java中其他無關問題報錯。

  • 編譯效率提高。v1中每次編譯app的時候都會重新生成綁定類,而在v2中則會保留已生成類,不會重新生成,提高效率。

  • v1中可以手動提供binding adapter覆蓋依賴庫中的adapter,而在v2當中,app中手動提供的binding adapter則只會對所應用到的library或module生效。

  • 不同配置資源文件夾下的同一個佈局文件中,如果存在同id不同類的View,則v1中會自動確定最通用的父類,而在v2中,則自動指定爲View類。

  • v2中不同module不能在manifest中使用相同包名,因爲V2使用包名來生成綁定類。

2. 設置佈局

DataBinding中的佈局文件需要在傳統的外層佈局套上一層標籤:

<layout>
    <FrameLayout/>
</layout>

編譯後會自動生成Binding類,類名以XML文件名的每個單詞首字母大寫,再加上Binding組合而成,比如activity_main.xml生成的類名是ActivityMainBinding。

在Android Studio當中,生成的綁定類位於app/build/generated/source/apt/debug/包名/databinding/ 目錄下。

如果要自定義生成的類名,可以在標籤中聲明class屬性進行設置。

3. 綁定佈局

在Activity中將佈局綁定到Activity上,獲取綁定類:

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
}

對於ListView或者RecyclerView中的綁定,可以使用以下兩種方式之一:

ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
// 或者
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);

注意在列表例如RecyclerView中,如果一個變量或者observable改變了,binding會在下一幀時改變,如果需要binding馬上執行,需要手動調用 executePendingBindings()

public void onBindViewHolder(BindingHolder holder, int position) {
   final T item = mItems.get(position);
   holder.getBinding().setVariable(BR.item, item);
   holder.getBinding().executePendingBindings();
}

DataBinding會爲佈局文件裏所有具備id的View生成相應public final的字段,字段名即id名。這是通過遍歷一次佈局層級完成的,會比對多個view調用findViewById()效率更高。

ViewStub

對於佈局中的ViewStub,DataBinding對應的生成類是ViewStubProxy,因爲ViewStub被inflate或者可見之後就被其他佈局替代了,所以DataBinding提供ViewStubProxy來獲取ViewStub以及inflated之後的佈局,inflate之前ViewStub非空,內含佈局爲空,inflate之後ViewStub爲空,內含佈局非空。

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