16
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Kotlin × Data BindingでonItemClickListener付きListViewアプリを作る

Last updated at Posted at 2017-02-11

KotlinとData Bindingを使ってListViewのアプリを作ります。
サンプルプロジェクトは、以下repositoryに格納しています。
https://github.com/shanonim/Kotlin-DataBinding-ListView

KotlinでData Bindingを使うための設定

build.gradleに以下を追記します。

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だったので、そちらを採用しています。
スクリーンショット 2017-02-11 14.21.41.png

表示するデータ

APIから取得するデータではなく、enumで定義したサンプルデータを表示します。

KemonoData.kt
enum class KemonoData(val kemonoName: String, val kemonoWords: String) {
    SERVAL("サーバル", "サーバルキャットのサーバルだよ!"),
    FENNEC("フェネック", "君、やっぱイケてるねー"),
    COMMON_RACCOON("アライグマ", "アライさんにお任せなのだー!"),
    KABAN("かばん", "(・8・)")
}
KemonoModel.kt
data class KemonoModel(val kemonoName: String, val kemonoWords: String)

ソースコード

Activity

MainActivity.kt
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>タグ内のtypeAdapterView.OnItemClickListenerをセットし、ListViewの子要素に対するonItemClickを設定しています。

activity_main.xml
<?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ファイルです。

item_list_view.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

KemonoAdapter.kt
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

参考にさせていただきました。ありがとうございます。:bow:

16
13
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
16
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?