新型コロナの影響で自宅待機になってしまい、その間勉強するものとしてSunflowerリポジトリを
勧めてもらいました。
JetPackのライブラリのうち、今回はDataBinding編です
尚、引用しているソースは明記しているところ以外は、全てSunflowerのリポジトリのものです。
環境
- 確認時は
Android Studioのバージョンは3.6.2を使用 -
Data bindingはサポートライブラリなので、Android 4.0(API レベル 14)以降で利用可能 -
Android Plugin for Gradleの1.5.0以降でサポートされているが、なるべく最新を使用したほうがいい(らしい)
DataBinding を利用するのに必要なこと
- ビルド環境設定
- レイアウトファイルを変更
- 購読処理の実施(LiveDataとの連携)
準備
Build.gradleファイルでData Bindingの機能を有効にします
Sunflowerではapp/build.gradleに記載してありますねー!(^^)
android {
compileSdkVersion rootProject.compileSdkVersion
dataBinding {
enabled = true
}
レイアウトファイル
ここではData Bindingを利用しているfragment_garden.xmlを見てみましょう
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="hasPlantings"
type="boolean" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/garden_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:layout_marginStart="@dimen/card_side_margin"
android:layout_marginEnd="@dimen/card_side_margin"
android:layout_marginTop="@dimen/margin_normal"
app:isGone="@{!hasPlantings}"
app:layoutManager="androidx.recyclerview.widget.StaggeredGridLayoutManager"
app:spanCount="@integer/grid_columns"
tools:listitem="@layout/list_item_garden_planting"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
app:isGone="@{hasPlantings}">
:
:
</LinearLayout>
</FrameLayout>
</layout>
ポイント
- レイアウトファイルが
<Layout>タグで開始されている。(<LinearLayout>とかじゃない) - その中に
<data>タグがある。 - さらにその中に
<variable>タグでバインディング変数を定義している - バインディング変数は
nameで名前を、typeで型を定義している - バインディング変数の利用箇所は
@{変数名}と記載する
ここでは、"@{hasPlantings}"と記載している
*ちなみに"@{viewModel.imageUrl}"のようなプロパティ参照もできる(list_item_garden_planting.xml参照)
ここではhasPlantingsの値によってRecyclerViewとなにもない時に表示するLinearLayoutを出し分けてますね
データのバインド
ではレイアウトファイルで記載した変数をどう関連付けるのか、Kotlinファイルを確認してみましょう
class GardenFragment : Fragment() {
private lateinit var binding: FragmentGardenBinding
:
:
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentGardenBinding.inflate(inflater, container, false)
val adapter = GardenPlantingAdapter()
binding.gardenList.adapter = adapter
binding.addPlant.setOnClickListener {
navigateToPlantListPage()
}
subscribeUi(adapter, binding)
return binding.root
}
:
:
}
ポイント
1. データバインディングを実施すると、バインディングクラスがレイアウトファイルごとに作られる。 作られるクラスの名称は下記のルールで決定されます
バインディング クラスはレイアウト ファイルごとに生成されます。
デフォルトのクラス名は、レイアウト ファイルの名前がパスカルケースに変換され、Binding サフィックスが付加されたものになります。
→ここの場合はfragment_garden.xmlのレイアウトファイルからFragmentGardenBindingクラスが作成されます
2. データバインディングの変数を利用するために、1.で自動生成されたバインディングクラスでinflate()します。
3. Fragment、ListView、RecyclerViewなどいずれかのアダプター内でデータバインディングの変数を利用する場合は、**DataBindingUtil#inflate()**メソッドも利用可能です
DataBindingUtil#inflate()利用箇所
GardenPlantingAdapterでは、DataBindingUtil#inflate()メソッドを利用してバインディングしていました。
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
R.layout.list_item_garden_planting, parent, false
)
)
}
購読処理の実施(LiveDataとの連携)
それでは、購読する処理を見てみましょう
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentGardenBinding.inflate(inflater, container, false)
:
:
subscribeUi(adapter, binding)
return binding.root
}
private fun subscribeUi(adapter: GardenPlantingAdapter, binding: FragmentGardenBinding) {
viewModel.plantAndGardenPlantings.observe(viewLifecycleOwner) { result ->
binding.hasPlantings = !result.isNullOrEmpty()
adapter.submitList(result)
}
名前の通りsubscribeUi()メソッドで購読処理を実施しています。
なるほどー。 ここでは、実際にレイアウトにバインディングしたhasPlantingsを直接購読しているのではなく、その情報を算出するためのplantAndGardenPlantingsをobserveしているんですね!
こうすることで、plantAndGardenPlantingsの値が変更された時にresultが更新されて、そこから算出された
hasPlantingsでRecyclerViewを更新すると。
ここから先はLiveData編に記載します!
参考サイト
- Sunflowerリポジトリ
- DataBinding: 公式ドキュメント
- LiveData: :公式ドキュメント