LoginSignup
6
6

More than 3 years have passed since last update.

[Android] Include タグを利用したときに Databinding する方法

Last updated at Posted at 2020-02-02

はじめに

Android では Layout の再利用性を高められるよう Include タグを利用すれば、
作成済みの Layout ファイルを他の Layout ファイルに埋め込むことができます。

作成済みの Layout ファイル
image.png

one_fragment.xml
    <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 ファイル

image.png

activity_main.xml
    <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 を簡単に再利用できます。

image.png

Databinding するデータを Include に反映させるには

Databinding では layout タグと data タグに利用するデータを
variable タグにて宣言しデータとビューをバインドできるようにします。

activity_main.xml
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable name="viewModel" type="kaleidot725.myapplication.MainViewModel" />
    </data>

      ︙
      ︙
</layout>

まずはInclude する場合も Databinding する手順はかわらず、
埋め込む側と埋め込まれる側の両方で必要なデータを宣言し利用します。

埋め込まれる側の Layout ファイル

image.png

one_fragment
<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 ファイル

image.png

activity_main.xml
<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

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をバインドする処理

MainActivity.kt
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}"
          
      />

この状態で起動すると、うまく動作します。

image.png

参考文献!

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6