KotlinとData Bindingを使ってListViewのアプリを作ります。
サンプルプロジェクトは、以下repositoryに格納しています。
https://github.com/shanonim/Kotlin-DataBinding-ListView
KotlinでData Bindingを使うための設定
build.gradle
に以下を追記します。
apply plugin: 'kotlin-kapt'
android {
dataBinding {
enabled = true
}
}
dependencies {
kapt 'com.android.databinding:compiler:2.2.3'
}
kapt 'com.android.databinding:compiler:
のversionは以下サイトを参考にしました。
https://bintray.com/android/android-tools/com.android.databinding.compiler
2017.02.11現在、stableの最新は2.2.3
だったので、そちらを採用しています。
表示するデータ
APIから取得するデータではなく、enumで定義したサンプルデータを表示します。
enum class KemonoData(val kemonoName: String, val kemonoWords: String) {
SERVAL("サーバル", "サーバルキャットのサーバルだよ!"),
FENNEC("フェネック", "君、やっぱイケてるねー"),
COMMON_RACCOON("アライグマ", "アライさんにお任せなのだー!"),
KABAN("かばん", "(・8・)")
}
data class KemonoModel(val kemonoName: String, val kemonoWords: String)
ソースコード
Activity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val binding : ActivityMainBinding
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
val listAdapter = KemonoAdapter(applicationContext)
val list = mutableListOf<KemonoModel>()
for (value in KemonoData.values()) {
list.add(KemonoModel(value.kemonoName, value.kemonoWords))
}
listAdapter.kemonoFriends = list
binding.listview.adapter = listAdapter
binding.setOnItemClick { adapterView, view, position, l ->
Toast.makeText(this, listAdapter.kemonoFriends[position].kemonoName, Toast.LENGTH_SHORT).show()
}
}
}
対応するxmlファイルはactivity_main.xml
です。
<variable>
タグ内のtype
にAdapterView.OnItemClickListener
をセットし、ListView
の子要素に対するonItemClick
を設定しています。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="onItemClick"
type="android.widget.AdapterView.OnItemClickListener" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
bind:onItemClickListener="@{onItemClick}" />
</LinearLayout>
</layout>
item_list_view
ListView
の子要素のxmlファイルです。
<?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>
<variable
name="kemonoFriends"
type="com.example.shanonim.kotlin_databinding_listview.model.KemonoModel" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="10dp"
android:paddingLeft="20dp"
android:paddingTop="10dp">
<TextView
android:id="@+id/text_view_kemono_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:width="500dp"
android:height="30dp"
android:gravity="center_vertical"
android:text="@{kemonoFriends.kemonoName}"
android:textColor="@android:color/black"
android:textSize="20dp"
tools:text="サーバル" />
<TextView
android:id="@+id/text_view_kemono_words"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/text_view_kemono_name"
android:width="500dp"
android:height="30dp"
android:gravity="center_vertical"
android:text="@{kemonoFriends.kemonoWords}"
android:textColor="@android:color/black"
tools:text="サーバルキャットのサーバルだよ!" />
</RelativeLayout>
</layout>
Adapter
class KemonoAdapter(private val context: Context) : BaseAdapter() {
var kemonoFriends: List<KemonoModel> = emptyList()
override fun getCount(): Int = kemonoFriends.size
override fun getItem(position: Int): Any? = kemonoFriends[position]
override fun getItemId(position: Int): Long = 0
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val binding: ItemListViewBinding
if (convertView == null) {
binding = ItemListViewBinding.inflate(LayoutInflater.from(context), parent, false)
binding.root.tag = binding
} else {
binding = convertView.tag as ItemListViewBinding
}
binding?.kemonoFriends = getItem(position) as KemonoModel
return binding.root
}
}
動作結果
ListView
の子要素をタップすると、それぞれのデータをToast表示します。
まとめ
ButterKnifeからData Bindingに乗り換える目的で今回のサンプルアプリを作りましたが、少ないコード量で求める機能を実現できたので、Data Bindingの有用性を確認することができました。
もっと良い方法やここはこうしたほうがいいなどありましたら、コメントやGitHubのPullRequestで教えて頂けると嬉しいです。
参考URL
参考にさせていただきました。ありがとうございます。
- KotlinでData Bindingを使う時の設定
http://qiita.com/umetsu/items/487d38be86c31ff59075 - KotlinでData Bindingをする - ListView編
http://qiita.com/kykomi/items/cb9020d37ae2b04af800 - DataBindingを使ったLayoutの作成(ソース編)
http://tiro105.hateblo.jp/entry/2016/03/23/000500