Playground

Kotlinで listView を Data Binding で実装してみる

Playground
この記事は約8分で読めます。
スポンサーリンク

お久しぶりです。もみじんです。

最近お仕事で Kotlin Android を使うことがあります。

3年前に触った時以来なので実装方法を思い出しつつ、今どきな方法を勉強しています。

どうやら今どきの方法(2023/02/12 現在)は、MVVMな感じで作る(Android公式では名言していないという話がありましたが、実質MVVMな感じと理解)のが主流ということがわかりました。

その要として、Data Binding を使用するということもわかりました。

ということで、この記事では、素人が listView を Data Binding を使って実装してみたという記事になります。

スポンサーリンク

実装してみた

作ったもの

素人なので、シンプルなものを作ってみました。

アイテムの追加ボタンを押すとListViewにアイテムが増え、アイテムの削除ボタンを押すとListViewのアイテムが消えるというものです。

動いている動画は以下に置きました。

https://github.com/Momijinn/mySampleAndroidListViewDataBinding/blob/main/README.md#%E5%8B%95%E7%94%BB

サンプルプログラム

サンプルプログラムは、Githubに上げました。

GitHub - Momijinn/mySampleAndroidListViewDataBinding
Contribute to Momijinn/mySampleAndroidListViewDataBinding development by creating an account on GitHub.

コード解説

前提

今回は、fragment の上に ListView を乗っけて、そのListViewにアイテムを追加していく実装にしました。

Data Bindig 設定

build.gradle に Data binding を使えるように宣言する。

android {
       ~~~   

    buildFeatures {
        dataBinding true
    }
}

ViewModelの定義

MainViewModel.kt

Viewとロジックを仲立ちするファイルを作ります。

ファイル名は、MainViewModel.kt にしました。

今回は、ListViewの中身はListで保持しようと思います。

そして、Listには Book というモデルがリスト化されています。(Bookについては後述します。)

private val _bookItems = MutableLiveData<List>(listOf())
val bookItems: LiveData<List> get() = _bookItems

また、Listの中身を追加したり削除したり、ボタンを押したくなるので、それらができる関数も追加しました。

fun seletexBook() -> タップされたBookを Toast表示
fun addBook() -> Book の追加
fun removeBook() -> Book の削除

レイアウトを Data Bindig 仕様にする

fragment_main.xml

data タグを追加し、その中に variable タグも追加する。

(variable が view と ロジックを仲立ちものという個人的な認識。)

レイアウトは適当にいい感じに書いています。

https://github.com/Momijinn/mySampleAndroidListViewDataBinding/blob/main/mySampleListView/app/src/main/res/layout/fragment_main.xml

カスタム ListView の実装

カスタム ListView で実装することが多いことを見越して、実装していきます。

book_item.xml

レイアウトは、単純な textView 一個だけにしました。

ここにも Data Bindig があります。

Book のデータクラスから title を android:text に渡しています。

https://github.com/Momijinn/mySampleAndroidListViewDataBinding/blob/main/mySampleListView/app/src/main/res/layout/book_item.xml
Book.kt

ListViewに表示させる Book データクラスが定義しています。

簡素な作りです。

https://github.com/Momijinn/mySampleAndroidListViewDataBinding/blob/main/mySampleListView/app/src/main/java/com/example/mysamplelistview/model/Book.kt
BookListBindingAdapter.kt

ListView の Adapter です。

カスタムListViewではおなじみのやつです。

Data Bindig では getView() の関数が特殊になります。

(book_item.xml と紐付けるをしている認識。)

override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
    val binding: BookItemBinding
    if(convertView == null){
        binding = BookItemBinding.inflate(inflater, parent, false)
        binding.root.tag = binding
    } else {
        binding = convertView.tag as BookItemBinding
    }
    binding.book = getItem(position) as Book

    return binding.root
}

ViewModelとロジックを紐付ける

MainFragment.kt

下準備ができたので、ViewModelとロジックを紐付けます。

 

onCreateView()  で fragment_main.xml と紐付けています。

また、fragment_main.xml 内にある ListView に対してBookListBindingAdapter を紐付けています。

binding = FragmentMainBinding.inflate(inflater, container, false)
        binding.vm = viewModel
        binding.lifecycleOwner = this

// listviewのadapterと紐付ける
if (viewModel.bookItems.value != null){
    binding.bookListView.adapter = BookListBindingAdapter(inflater.context,
        viewModel.bookItems.value!!
    )
}

 

onViewCreated() では ListViewのアイテム監視と、レイアウトにあるボタンのイベント受け取りを実装しています。

 

ListViewのアイテム監視は以下の箇所でしています。

アイテムが増えたり減ったりすると、この関数のイベントが発火します。

中身は、listview の中身の再定義です。

// bookList の値を監視する
viewModel.bookItems.observe(viewLifecycleOwner) { bookList ->
    binding.bookListView.adapter = BookListBindingAdapter(view.context, bookList)
}

 

他の箇所は、ボタンイベントになります。

ボタンが押されると ViewModelに定義してある関数が呼ばれます。

// listviewのアイテムクリック
binding.bookListView.setOnItemClickListener { adapter, view, position, _ ->
    val book = adapter.getItemAtPosition(position) as Book
    viewModel.selectedBook(view.context, book)
}

// itemの追加ボタン
binding.bookAddButton.setOnClickListener {
    viewModel.addBook()
}

// itemの削除ボタン
binding.bookRemoveButton.setOnClickListener {
    viewModel.removeBook()
}

まとめ

Kotlinで listView を Data Binding で実装してみました。

はじめは理解するのに時間がかかりましたが、なれるとすごく楽だなと感じます。

以前は、Viewとロジックがごっちゃになってかなり見づらいコードになってしまいましたが、このおかげでかなり見やすくなったと思います。

仕事でもバンバン使っていきたいと思います。

参考文献

コメント

タイトルとURLをコピーしました