【はじめてのKotlinプログラミング(38)】RecyclerViewでToDoアプリ(後編:リストアイテムの削除)

前編「リストの追加」はこちら

前回の動画で、入力した文字をリストに追加するということができるようになりました。今回はその続きで、タッチしたアイテムをRemove、つまり削除する、という処理をしていきたいと思います。

完成後、軽めのwarningが3つほど出ていると思いますので、それの修正については次のページで

動画

目次

タイトル 再生時間
[12]タッチ処理 00:00~
[13]トーストで表示してみる 04:35~
[14]アラートダイアログ 08:05~
[15]Yesボタンを押したら~ 11:20~
[16]画面の更新 15:15~

コード

▼activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <EditText
        android:id="@+id/et"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:hint="何か書いて"
        android:textSize="24sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:text="+"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="24dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/et" />
</androidx.constraintlayout.widget.ConstraintLayout>

▼one_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:text="TextView"
        android:textSize="24sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

▼TodoData.kt

package com.example.recyclertodo

data class TodoData(
    val myTodo :String
)

▼RecyclerAdapter.kt

package com.example.recyclertodo

import android.app.AlertDialog
import android.content.DialogInterface
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView

//5)リストを用意 クラス名(private val 変数名:ArrayList<データクラス>) //or MutableList
class RecyclerAdapter(private val todoList:ArrayList<TodoData>) :RecyclerView.Adapter<RecyclerAdapter.ViewHolderItem>() {
    //listOf

    //5)ViewHolder(インナークラス)
    //16),rAdapter : RecyclerAdapter// RecyclerAdapterを受け取る
    inner class ViewHolderItem(v:View,rAdapter:RecyclerAdapter) :RecyclerView.ViewHolder(v) {
        val tvHolder : TextView = v.findViewById(R.id.tv)

        //12)クリック処理(1行分の画面(view)が押されたら~)
        init {
            v.setOnClickListener {
                val position:Int = adapterPosition
                val listPosition = todoList[position]

                //14)アラートダイアログ
                AlertDialog.Builder(v.context)
                    .setTitle("${listPosition.myTodo}")
                    .setMessage("本当に削除しますか")
                    //15)yesボタンを押した時の処理
                    .setPositiveButton("Yes",DialogInterface.OnClickListener { _, _ ->
                        todoList.removeAt(position)
                        //16)表示を更新
                        rAdapter.notifyItemRemoved(position)
                    })
                    .setNegativeButton("No",null)
                    .show()

                //13)トーストでposition番目を表示してみる
                //Toast.makeText(v.context,"$listPosition",Toast.LENGTH_SHORT).show()
                //Toast.makeText(v.context,"${listPosition.myTodo}",Toast.LENGTH_SHORT).show()
            }
        }
    }

    //6)一行だけのViewを生成
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolderItem {
        val itemXml = LayoutInflater.from(parent.context)
            .inflate(R.layout.one_layout,parent,false)
        return ViewHolderItem(itemXml,this) //16)RecyclerAdapterを受け渡す
    }

    //7)position番目のデータをレイアウト(xml)に表示するようセット
    override fun onBindViewHolder(holder: ViewHolderItem, position: Int) {
        val currentItem = todoList[position] //何番目のリスト(アイテム)ですか
        holder.tvHolder.text = currentItem.myTodo //そのリストの中の要素を指定して代入
    }

    //8)リストサイズ
    override fun getItemCount(): Int {
        return todoList.size
    }
}

▼MainActivity.kt

package com.example.recyclertodo

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class MainActivity : AppCompatActivity() {
    //9)追加リストと、RecyclerViewと、アダプターを用意
    private var addList =ArrayList<TodoData>() //空っぽのリストを用意<型はデータクラス>
    private lateinit var recyclerView : RecyclerView
    private var recyclerAdapter = RecyclerAdapter(addList) //アダプターに追加リストをセット

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //10)viewの取得、アダプターにセット、レイアウトにセット
        recyclerView = findViewById(R.id.rv)
        recyclerView.adapter = recyclerAdapter
        recyclerView.layoutManager = LinearLayoutManager(this)

        //11)追加ボタンを押したら~
        val btnAdd : Button = findViewById(R.id.btnAdd)
        btnAdd.setOnClickListener {
            val et :EditText = findViewById(R.id.et)
            val data =TodoData(et.text.toString())
            addList.add(data)
            recyclerAdapter.notifyItemInserted(addList.lastIndex) //表示を更新(リストの最後に挿入)

            et.text = null
        }
    }
}

【参考】

kotlin android how to add and delete item in recyclerview/android how to add popup menu recyclreview

RecyclerView:アイテムの変更(Change/Insert/Move/Remove)

RecyclerViewをAdapter.notifyDataSetChanged()を用いて更新できなかった理由を考察してみた

    コメントを残す