[Kotlin] ListViewのリスト項目をタップした際のイベント処理

2018年1月15日(更新: 2018年4月26日)

以前 Kotlin による基本的な ListView の作成方法について紹介しました。

今回は上記の記事で作成した ListView の項目をタップした際のイベント処理について紹介します。また、リスト項目を挿入・削除する方法についても解説します。

サンプルアプリの動作

以下の動作を行う ListView を表示するアプリを例に、タッチイベントの設定方法を解説します。

  • リストの最後の項目「+」をクリックすると、その上に新しいリスト項目を追加する
  • リストの最後以外の項目を長押しすると、その項目を削除する

アプリを起動すると、以下のようなリストが表示されます。

ListViewで作成したリスト

一番下の項目「+」をタップすると、新しいリスト項目がその上に追加されます。

insertによってListViewにアイテムを追加

「+」以外の項目を長押しすると、その項目を削除することができます。以下は「Android」を削除した後のリストです。

ListViewからremoveで項目を削除

サンプルアプリのプログラム

レイアウトXMLで画面に ListView を配置し、そのリストにプログラム(Kotlin)で項目とクリックしたときの処理を設定します。

activity_main.xml

レイアウトを設定するXMLの中身は以下の通りです。前回のものと全く同じです。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.test.MainActivity" >

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

MainActivity.kt

Kotlin のプログラムです。リストの最後に「+」というテキストの項目と、タップした時と長押ししたときの処理を追加しています。

package com.example.test

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.ArrayAdapter
import android.widget.ListView
import android.widget.TextView

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val arrayAdapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1).apply {
            add("Android")
            add("iOS")
            add("Windows")
            add("macOS")
            add("Unix")
            add("+") // 追加
        }

        val listView : ListView = findViewById(R.id.listView)
        listView.adapter = arrayAdapter

        // 項目をタップしたときの処理
        listView.setOnItemClickListener {parent, view, position, id ->

            // 項目の TextView を取得
            val itemTextView : TextView = view.findViewById(android.R.id.text1)

            // 項目のラベルテキストをログに表示
            Log.i("debug", itemTextView.text.toString())

            // 一番下の項目をタップしたら新しい項目をその項目の上に追加
            if (position == arrayAdapter.count - 1) {
                arrayAdapter.insert("New Item " + arrayAdapter.count, arrayAdapter.count - 1)
                arrayAdapter.notifyDataSetChanged()
            }
        }

        // 項目を長押ししたときの処理
        listView.setOnItemLongClickListener { parent, view, position, id ->

            // 一番下の項目以外は長押しで削除
            if (position == arrayAdapter.count - 1) {
                return@setOnItemLongClickListener false
            }

            arrayAdapter.remove(arrayAdapter.getItem(position))
            arrayAdapter.notifyDataSetChanged()

            return@setOnItemLongClickListener true
        }

    }
}

リスト項目のクリックを処理するには setOnItemClickListener を使用します。

listView.setOnItemClickListener {parent, view, position, id -> {
    // リスト項目をタップしたときの処理
}

同じように、長押しを処理する場合は setOnItemLongClickListener を使用します。

setOnItemLongClickListener が setOnItemClickListener と違う点は、イベントが正しく処理されたか(別の View にイベントを伝播させるか)を Boolean で返すところです。

listView.setOnItemLongClickListener {parent, view, position, id -> {
    // リスト項目を長押ししたときの処理

    return@setOnItemLongClickListener true
}

どちらも第3引数の position には、リスト項目の番号が格納されています。一番上の項目の番号が 0 です。

今回はこの値を利用して、項目の最後の要素であるかどうか、つまり position の値が (要素数 – 1) と等しいかどうかを調べて処理の分岐を行っています。

リストのテキストを取得

リスト項目のテキストを表示している TextView には android.R.id.text1 というIDが設定されていますので、これで項目のテキストを得ることができます。

val itemTextView : TextView = view.findViewById(android.R.id.text1)
Log.i("debug", itemTextView.text.toString())

リスト項目の挿入・削除

ArrayAdapter のメソッド insert で項目の追加、remove で項目の削除ができます。

insert の第2引数には、項目を挿入する位置を指定します。

arrayAdapter.insert(項目のテキスト, 挿入位置)

remove は、削除する番号ではなく、削除する項目の要素(今回はテキストなのでString)を引数に指定します

arrayAdapter.remove(削除対象の要素)

ArrayAdapter の getItem を使用して、その番号の要素を得ることができます。

これらのメソッドで項目を変更したら notifyDataSetChanged によって変更を同期させます。

おしまい

以上が ListView におけるタップや長押しのイベント処理と、項目の挿入や削除の方法です。

これらを組み合わせることで、項目を動的に変更できるリストが作れます。

[Kotlin] ListViewのリスト項目をタップした際のイベント処理」への2件のフィードバック

  1. ピンバック: [Kotlin] ListViewでAndroidアプリにリストメニューを表示 - JoyPlotドキュメント

  2. ピンバック: [Kotlin] ListViewの項目にボタン付きの自作レイアウトを設定 - JoyPlotドキュメント

コメントを残す

メールアドレスが公開されることはありません。