【Android Studio】RecyclerViewでリストを作りたい



RecyclerView


RecyclerViewは、同じくリストを扱うListViewを拡張したものです。


activity_main.xml


まず、activity_main.xmlにRecyclerViewを配置してみます。

<?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">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>


RecyclerViewを利用するには、build.gradleにこちらを記述する必要があります。(バージョンは個々に指定)

dependencies {
  implementation 'androidx.recyclerview:recyclerview:1.1.0'
}


one_item.xml


RecyclerView内の1行レイアウトを、one_item.xmlで指定しています。
今回は適当にTextViewを配置しました。

<?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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="60dp">

    <TextView android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:id="@+id/textview"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginTop="8dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginEnd="8dp"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginStart="8dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>

RecyclerViewの代表的なサブクラス

LayoutManagerレイアウトを決める
ViewHolder1行分のデータを管理
AdapterデータとViewの橋渡しをする

OneItem

one_item.xmlに対応するクラスをOneItemとして実装しています。



class OneItem() {
    var text:String = ""
}


ViewHolder

//RecyclerView.ViewHolder(itemView)を継承


ViewHolderでは、one_item.xmlでのレイアウト要素をプロパティとして持ちます。
ここではTextViewのみですが、init内で対応づけています。

import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.one_item.view.*

class ViewHolder(itemView : View): RecyclerView.ViewHolder(itemView) {
    var text: TextView? = null

    init {
        text = itemView.textview
    }
}


Adapter

class CustomRecyclerViewAdapter(list : MutableList<OneItem>): RecyclerView.Adapter<ViewHolder>() {
        private val list:MutableList<OneItem> = list

        override fun onCreateViewHolder(parent: ViewGroup, position: Int): ViewHolder {
            val inflater = LayoutInflater.from(parent.context)
            val view = inflater.inflate(R.layout.one_item,parent,false)    
            val viewholder = ViewHolder(view)
            return viewholder
        }

        override fun getItemCount(): Int {
            return list.size
        }

        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            val item = list[position]
            holder.text?.text = item.text
        }
    }

onCreateViewHolder
・LayoutInflater.from … LayoutInflaterを生成
・inflater.inflate… xmlレイアウトからviewを生成
・ViewHolder(view)…引数に生成したviewを指定してViewHolderを生成

getItemCount
アイテムの総数を返す

onBindViewHolder
ViewHolderを指定し、その内容を更新


MainActivity

private lateinit var adapter:CustomRecyclerViewAdapter
    private lateinit var layoutManager: RecyclerView.LayoutManager
    private lateinit var itemDecoration: DividerItemDecoration
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
    override fun onStart() {
        super.onStart()

        //区切り線
        itemDecoration = DividerItemDecoration(this,DividerItemDecoration.VERTICAL)
        recyclerView.addItemDecoration(itemDecoration)
     
     //LayoutManager
        layoutManager = LinearLayoutManager(this)
        recyclerView.layoutManager=layoutManager

        //Adapter
        adapter = CustomRecyclerViewAdapter(makeRecyclerData())
        recyclerView.adapter = this.adapter
  
        //スワイプ操作
        val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP or ItemTouchHelper.DOWN, ItemTouchHelper.LEFT) {

            override fun onMove(
                recyclerView: RecyclerView,
                viewHolder: RecyclerView.ViewHolder,
                target: RecyclerView.ViewHolder
            ): Boolean {
                val from = viewHolder.adapterPosition?:0
                val to = target.adapterPosition?:0
                recyclerView.adapter?.notifyItemMoved(from,to)
                return true
            }

            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                viewHolder.let{
                    recyclerView.adapter?.notifyItemRemoved(viewHolder.adapterPosition)
                }
            }})
        itemTouchHelper.attachToRecyclerView(recyclerView)
    }

  //アイテム(n)と描画
    fun makeRecyclerData():MutableList<OneItem>{
        var recyclerData :MutableList<OneItem> = mutableListOf()
        for(i in 0..50){
            var oneitem:OneItem= OneItem()
            oneitem.text="アイテム"+i.toString()
            recyclerData.add(oneitem)
        }
        return recyclerData
    }


DividerItemDecoration
DividerItemDecoration(this,DividerItemDecoration.VERTICAL)で区切り線を実装しています。RecyclerViewにはデフォルトでは区切りがないため、このようにする必要があります。

LayoutManager
RecyclerViewにLinearLayoutManagerを設定

Adapter
データセットをmakeRecyclerDataで生成し、そのリストを元にadapterを生成


スワイプ操作
上の動画のように、スワイプ操作でのアイテム削除を実装しています。
アイテムに対する操作は、ItemTouchHelperクラスのオブジェクトを生成することで行います。
ItemTouchHelperクラスのコンストラクタには、引数としてItemTouchHelper.Callbackクラスのオブジェクトが必要です。

ItemTouchHelper  |  Android Developers
Public constructors
<init>(@NonNull callback: ItemTouchHelper.Callback)

AndroidではItemTouchHelper.Callbackを継承したSimpleCallbackが用意されていますので、そちらを用います。

https://developer.android.com/reference/kotlin/androidx/recyclerview/widget/ItemTouchHelper.SimpleCallback

abstract class SimpleCallback : ItemTouchHelper.Callback

//コンストラクタの引数例
<init>(dragDirs: Int, swipeDirs: Int)

・onMove…ドラッグ操作
・onSwipe…スワイプ操作
をそれぞれ扱います。


以上で、RecyclerViewの基本的な操作ができるようになります。
スワイプ時のさらなる挙動については、こちらの記事でまとめています。

コメント

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