Android ListViewに変更を通知する


一度、表示されたListViewに対して変更された内容を通知する方法。

よくあるケースとして

  • セルデータの編集・削除を行った
  • ネットワークを通じて新しいデータを取得

などが想定されます。

例としてListViewのitemを長押しして選択対象を削除するというユースケースの処理を記述します。

基本のListView出力

class MainActivity : AppCompatActivity() {

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

        val listData = arrayListOf<String>("a", "b", "c")
        listView = findViewById<ListView>(R.id.list_view)
        val adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listData)
        listView.adapter = adapter
}

長押しイベントの取得

長押しイベントはOnItemLongClickListener()で取得します。kotlinで記述すると以下の通り。Booleanの戻り値が必要。

listView.setOnItemLongClickListener { parent, view, position, id ->
    true
}

長押しイベントの実装

adapterに渡したArrayListの指定indexを削除。データ変更の通知はadapterのnotifyDataSetChanged()メソッドで通知します。

listView.setOnItemLongClickListener { parent, view, position, id ->
    listData.removeAt(position)
    adapter.notifyDataSetChanged()
    true
}

配列差替え時の注意

全リフレッシュをするような時に

var listData = arrayListOf<String>("a", "b", "c")
listView = findViewById<ListView>(R.id.list_view)
val adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listData)
listView.adapter = adapter
//ArrayListをリフレッシュ
listData = arrayListOf<String>("e", "f", "g")
adapter.notifyDataSetChanged()

としても、val listData = arrayListOf<String>("e", "f", "g")で別のarrayListOfオブジェクトが生成される(adapterに渡したArrayListとは別オブジェクトになる)ので、更新されません。clear()後にadd()することで解決。または新しいadapterを作成します。

clear()を利用の例

listData.clear()
listData.add("e")
listData.add("f")
listData.add("g")
adapter.notifyDataSetChanged()

新しいadapter作成の例 この場合はnotifyDataSetChanged()は必要ありません。

listData = arrayListOf<String>("e", "f", "g")
listView.adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listData)