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 | レイアウトを決める |
ViewHolder | 1行分のデータを管理 |
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クラスのオブジェクトが必要です。
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の基本的な操作ができるようになります。
スワイプ時のさらなる挙動については、こちらの記事でまとめています。
コメント