RecyclerViewの基本的な使い方と動的にリストを作る方法を説明しています。
RecyclerViewとは?何ができるか
一覧形式のリストを動的に生成することが可能です。
読み込んだデータを初期値として表示したり、アプリ上で入力したデータを一覧に追加するといったことが出来ます。
この後に例として示すのは、入力したテキストを画面に反映していくものとなっています。
実装に必要なファイル
RecyclerViewの実装にあたり、以下のファイルが必要となります。
- Adapterクラス
リストに表示するデータを画面上にバインドするためのクラス - Dataクラス
リストに表示する項目を定義しておくクラス - リスト項目のレイアウトファイル
リストに表示する一行ごとのレイアウト
実装例
レイアウト
activity_main.xml
メインアクティビティのレイアウトです。
上から順に以下のコンポーネントを配置します。
- EditText
リストへ追加するテキストを入力する - Button
入力したテキストをリストに追加するトリガー - RecyclerView
動的に生成するリスト
※heightに”match_parent”を指定すると、画面一杯覆ってしまうことがあります。コンポーネント同士が重ならないように調整しましょう。
row_item.xml
リスト項目のレイアウトで、すべての行において共通で使用されます。
今回はテキストを入力するだけなので、TextViewを配置します。他にも表示したい項目がある場合は、このレイアウトに追加していきます。
実装方法
PersonData.kt
リストに表示する項目を定義します。
data class PersonData( var name: String )
CustomAdapter.kt
RecyclerView.Adapterを継承したカスタムクラスを作成、以下のメソッドを実装します。
インスタンス生成時に渡される”dataSet”を各メソッドで処理していく流れとなっています。
メソッドの役割について示します。
- ViewHolder
カスタムクラス内で参照する情報を定義しておく - onCreateViewHolder
リスト項目(row_item.xml)のviewを生成 - onBindViewHolder
“dataSet”から取得される値をバインドする - getItemCount
リストのサイズを取得する
class CustomAdapter(private val dataSet: MutableList<PersonData>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() { //カスタムクラス内で参照する情報を定義 class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val textViewName: TextView = view.findViewById(R.id.textViewName) } //リスト行に使用するレイアウトのviewを生成 override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(viewGroup.context) .inflate(R.layout.row_item, viewGroup, false) return ViewHolder(view) } //画面内のコンポーネントにデータをバインド override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { viewHolder.textViewName.text = dataSet[position].name } //リストサイズを取得 override fun getItemCount() = dataSet.size }
MainActivity.kt
アプリ起動時にリストを表示、ボタンによるデータの追加処理を実装しています。
private var personList: MutableList<PersonData> = ArrayList<PersonData>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //RecyclerViewコンポーネントの取得 val recyclerView: RecyclerView = findViewById(R.id.recyclerView) //LinearLayoutの取得 val linearLayoutManager = LinearLayoutManager(this) //バインド用のadapterにリストを関連付け val adapter = CustomAdapter(personList) //RecyclerViewコンポーネントに設定 recyclerView.layoutManager = linearLayoutManager recyclerView.adapter = adapter //画面更新用ボタン val buttonUpdate: Button = findViewById(R.id.buttonUpdate) buttonUpdate.setOnClickListener { //画面に入力したテキストを取得 val editTextName: EditText = findViewById(R.id.editTextName) val data = PersonData(editTextName.text.toString()) //adapterに設定したリストに追加 personList.add(data) //リストへの追加を通知(画面更新) adapter.notifyItemInserted(personList.lastIndex) } }
順番に説明していきます。
//LinearLayoutの取得 val linearLayoutManager = LinearLayoutManager(this)
LinearLayoutManagerはレイアウトを管理するためのクラスです。これをRecyclerViewコンポーネントに設定すると、自動で生成してくれます。
//バインド用のadapterにリストを関連付け val adapter = CustomAdapter(personList)
作成しておいたCustomAdapterのインスタンスを生成します。引数には、画面上に表示するデータを指定します。
//RecyclerViewコンポーネントに設定 recyclerView.layoutManager = linearLayoutManager recyclerView.adapter = adapter
これより前で生成した”LayoutManager”と”Adapter”をRecyclerViewコンポーネントに設定します。
ここまでで、画面上に表示する準備は出来ました。CustomAdapterのインスタンス生成時に指定した引数にデータを入れておけば、初期表示も行えます。
ここからは、動的にリストへ追加する方法です。
//画面更新用ボタン val buttonUpdate: Button = findViewById(R.id.buttonUpdate) buttonUpdate.setOnClickListener { //画面に入力したテキストを取得 val editTextName: EditText = findViewById(R.id.editTextName) val data = PersonData(editTextName.text.toString()) //adapterに設定したリストに追加 personList.add(data) //リストへの追加を通知(画面更新) adapter.notifyItemInserted(personList.lastIndex) }
テキストに入力した値をpersonList(バインドしたデータ)へ追加→notifyItemInsertedによる通知(画面更新)という流れです。
ここで大事なのは、この部分です。
//リストへの追加を通知(画面更新) adapter.notifyItemInserted(personList.lastIndex)
テキストに入力した値をpersonList(バインドしたデータ)へ追加しただけでは画面の更新は行われません。通知を行うことで、画面の更新を自動で行ってくれるようになります。
今回の例では、末尾にデータを追加しているため、personList.lastIndexを引数として渡しています。これは、リストの最後にデータを追加したことを意味しています。リストの最初に追加する場合は”0”、途中に追加した場合は追加した位置を指定します。
リスト全体を更新する場合はnotifyDataSetChanged、リストから削除した場合はnotifyItemRemovedを使用します。
まとめ
RecyclerViewの基本的な使い方と動的にリストを作る方法を説明しました。
RecyclerViewを利用すると一覧形式での表示を行うことが可能で、行単位のレイアウトも自由にカスタマイズできます。
カスタムクラスを作成して実装する必要がありますが、単純なリストであれば示した実装例をテンプレートとして使用することが可能です。
リストを更新したら”notify~”メソッドを使用して、画面更新を行うことを忘れないようにしましょう。