はじめに
Android では Layout の再利用性を高められるよう Include タグを利用すれば、
作成済みの Layout ファイルを他の Layout ファイルに埋め込むことができます。
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Good Sample"
android:textSize="32sp"
/>
</FrameLayout>
他の Layout ファイルを埋め込んだ Layout ファイル
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/zero_text_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:gravity="center"
android:text="This is"
android:textSize="32sp"
app:layout_constraintBottom_toTopOf="@id/one_include"
app:layout_constraintTop_toTopOf="parent" />
<include
android:id="@+id/one_include"
layout="@layout/one_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/zero_text_view"/>
</androidx.constraintlayout.widget.ConstraintLayout>
アプリを実行すると次のように表示されます。
このように Include タグを利用すれば Layout を簡単に再利用できます。
Databinding するデータを Include に反映させるには
Databinding では layout タグと data タグに利用するデータを
variable タグにて宣言しデータとビューをバインドできるようにします。
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable name="viewModel" type="kaleidot725.myapplication.MainViewModel" />
</data>
︙
︙
</layout>
まずはInclude する場合も Databinding する手順はかわらず、
埋め込む側と埋め込まれる側の両方で必要なデータを宣言し利用します。
埋め込まれる側の Layout ファイル
<layout>
<data>
<variable name="viewModel" type="kaleidot725.myapplication.MainViewModel" />
</data>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@{viewModel.oneLayoutMessage}"
android:textSize="32sp"
/>
</FrameLayout>
</layout>
埋め込む側の Layout ファイル
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable name="viewModel" type="kaleidot725.myapplication.MainViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/zero_text_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:gravity="center"
android:text="@{viewModel.activityLayoutMessage}"
android:textSize="32sp"
app:layout_constraintBottom_toTopOf="@id/one_include"
app:layout_constraintTop_toTopOf="parent" />
<include
android:id="@+id/one_include"
layout="@layout/one_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/zero_text_view"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
MainViewModel
class MainViewModel : ViewModel() {
private val _activityLayoutMessage: MutableLiveData<String> = MutableLiveData("This is")
val activityLayoutMessage: LiveData<String> = _activityLayoutMessage
private val _oneLayoutMessage: MutableLiveData<String> = MutableLiveData("Good Sample")
val oneLayoutMessage: LiveData<String> = _oneLayoutMessage
}
そして MainAcitvity にて ViewModel を設定する処理を
記述すれば通常は Databinding できるようになります。
MainViewModelをバインドする処理
class MainActivity : AppCompatActivity() {
private val viewModel by viewModels<MainViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main).apply {
viewModel = this@MainActivity.viewModel
lifecycleOwner = this@MainActivity
}
}
}
ですが今回は Include を利用しているので、もう1つ記述が必要になります。
なぜなら MainAcitivty にて ViewModel を設定する処理だけでは、
Include した箇所にまで ViewModel を設定してくれないからです。
Include した箇所にも反映させるには、Includeタグに app:Variable名称 設定する必要があります。
<include
android:id="@+id/one_include"
app:viewModel="@{viewModel}"
︙
/>
この状態で起動すると、うまく動作します。