Kotlinで DataBinding を実装するまえに整理してみたメモ
個人メモです。
これからDataBindingしてみようという方へ簡単なサンプルを作成しました。
DataBinding とは
乱暴に言ってしまうと、Viewに対する操作をView上に記述できるようにする仕組み。
通常はControllerでViewを取得して、View上にオブジェクトを配置するなどの作業が必要。
これをやめてViewの中でController内のオブジェクトに相当する何かを操作して、Viewに対する処理を行う。更に言えば、View上で行なった操作結果がControllerにも返すような仕組み。双方向という場合はここまでを指す。
実例によってDataBindingの仕組みでも使ったり使わなかったりするものもあるのであとはやらかしながら確かめるしかない。。。
プロジェクト作成
普通にAndroidStudioでプロジェクトを作成する。プロジェクト名はKotlinDataBindingSample
build.gradle編集
add 以下を追加
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
// add
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.kotlindatabindingsample"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
// add
dataBinding {
enabled = true
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
buildscript {
ext.kotlin_version = '1.3.31'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
// add
classpath 'com.android.tools.build:gradle:1.3.0-beta1'
classpath "com.android.databinding:dataBinder:1.0-rc0"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
一度起動してみてエラーがないことを確認
Model作成
データを保持するクラス、、、構造体みたいなのを作成。
このモデルの内容をViewで参照できるようにする。
package com.example.kotlindatabindingsample.model
data class User(val name: String, val age: Int)
View編集
アクティビティ内で生成したUserモデルのデータを表示できるように
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View"/>
<variable name="user"
type="com.example.kotlindatabindingsample.model.User"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.kotlindatabindingsample.MainActivity">
<TextView
android:id="@+id/user_name_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.name}"
/>
<TextView
android:id="@+id/user_age_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{Integer.toString(user.age)}"
android:visibility="@{user.age >= 18 ? View.VISIBLE : View.GONE}"
/>
</LinearLayout>
</layout>
- DetaBindingするレイアウトは、
<layout></layout>
で括る。 - レイアウト内で利用する変数は、
<data> <variable ~ /> </data>
で宣言する。 - 宣言した変数の使い方は、@{user.name}のように、@{ ~ }で記述する。
- 18歳未満は表示しない
android:visibility="@{user.age >= 18 ? View.VISIBLE : View.GONE}"
などの機能を使う場合は、dataタグ内に<import type="android.view.View"/>
を記述しておく。
一旦起動
この辺りで一旦起動しておく。activity_main.xml
に対するDataBindingを中継するクラス<パッケージ名>.ActivityMainBinding
が自動的に生成される。
このクラスはAndroidStudioからは参照できない(?)ので注意。コンパイルすれば自動的に生成されるっぽい。
MainActivityクラスの編集
package com.example.kotlindatabindingsample
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import com.example.kotlindatabindingsample.databinding.ActivityMainBinding
import com.example.kotlindatabindingsample.model.User
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val binding: ActivityMainBinding =
DataBindingUtil.setContentView(this, R.layout.activity_main)
val user = User("sample 25歳", 25)
binding.user = user
}
}
ActivityMainBinding
クラスを使って、activity_main.xml
へのDataBindingを宣言する。
binding.user
に代入したオブジェクトが、Viewでは{@user.〜}
という風に使える。
MainActivity
クラスでは、Viewで利用したいオブジェクトを定義するだけ。
Viewを取得してViewどこかに配置する、などの処理は行わない。
実行結果
- 25歳の場合は、年齢まで表示
- 14歳の場合は、18歳未満なので年齢は表示しない