RecyclerViewを使ってSimple List Itemのような表示をするまで
RecyclerView
はじめに
ListViewは簡単なリスト表示によく利用されますが、操作がタップ関連のみ(タップ・ロングタップ)となっています。
そのため、iOSと同じようにスワイプを利用した機能を実装する際には力不足となってしまいます。
それらを解決するためにRecyclerViewという新たなListViewが追加されました。
今回はこのRecyclerViewを使ってListViewのSimple List Itemのようにテキストを表示する方法を紹介したいと思います。
環境
- AndroidStudio 3.1.2
- Kotlin 1.2.41
- compileSdkVersion 27
で動作確認を行ないました。 また、Kotlin Android Extensionsを利用しています。利用しない場合の記述とは異なる場合があります。
準備
RecyclerViewを表示するためにはcom.android.support:design
ライブラリをインポートする必要があります。
アプリのbuild.gradleを以下のように追記します。
dependencies { ... implementation 'com.android.support:design:27.1.1' }
これでRecyclerViewを利用することが出来ます。
RecyclerViewの実装
RecyclerViewを表示するには次の3つを実装する必要があります。
- Adapter
- ViewHolder
- セルのレイアウト
AdapterはListViewと同じですが、ViewHolderというものを新たに実装する必要があります。
これはListViewのgetItemに相当します。
また、RecyclerViewにはListViewのようにデフォルトのレイアウトが存在しません。
そのため今回のように簡単なレイアウトでも独自にレイアウトを作成する必要があります。
それでは実際に実装していきます。 実装の際は
- セルのレイアウト
- ViewHolder
- Adapter
の順番で実装していくと、補完を利用できるため楽です。
セルのレイアウト
RecyclerViewのレイアウトは注意点が2つあります。
1つ目はルート要素がLinearLayout
でなければならない。
2つ目は要素のHeightが決定されるようにする*1。
これらに注意してセルのレイアウトを実装すると以下のようになります。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/text" android:layout_width="match_parent" android:layout_height="48dp" android:gravity="center_vertical" android:text="center" /> </LinearLayout>
ViewHolder
レイアウトに配置したViewの参照を保持するだけなので、コード自体はシンプルです。
import android.support.v7.widget.RecyclerView import android.view.View import android.widget.TextView import kotlinx.android.synthetic.main.holder_view_recycler.view.* class RecyclerViewHolder(var view: View) : RecyclerView.ViewHolder(view) { val text: TextView = view.text }
Adapter
import android.content.Context import android.support.v7.widget.RecyclerView import android.view.LayoutInflater import android.view.ViewGroup class RecyclerViewAdapter(var items: List<String>) : RecyclerView.Adapter<RecyclerViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder { val layoutInflater = LayoutInflater.from(parent.context) val view = layoutInflater.inflate(R.layout.holder_view_recycler, parent, false) return RecyclerViewHolder(view) } override fun getItemCount(): Int { return items.size } override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) { holder.text.text = items.get(position) } }
ListViewのadapterと違い、onCreateViewHolder
とonBindViewHolder
の2つでgetView
に相当する動作を行ないます。onCreateViewHolder
でセルのViewを生成し、onBindViewHolder
でデータを反映させます。
getItemCount
はListViewの場合と同じく、リストで表示する要素の個数を返します*2。
RecyclerViewの表示
アクティビティのレイアウト
RecyclerViewを画面いっぱいに表示します。
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.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"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>
今回はアクティビティなのでConstraintLayoutが使えます。
表示処理
それでは実際にRecyclerViewを表示します。
import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.support.v7.widget.DividerItemDecoration import android.support.v7.widget.LinearLayoutManager import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // LayoutManagerの設定 val layoutManager = LinearLayoutManager(this) recycler_view.layoutManager = layoutManager // Adapterの設定 val sampleList = mutableListOf<String>() for (i in 0..10) { sampleList.add(i.toString()) } val adapter = RecyclerViewAdapter(sampleList) recycler_view.adapter = adapter // 区切り線の表示 recycler_view.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL)) } }
LayoutManager
を設定でLinearLayoutManager
を使うため、レイアウト作成時にはLinearLayout
を使う必要がありました。
Adapterは今回はString型のリストを作成しadapter
に渡しています。
RecyclerManager
はデフォルトでは区切り線が表示されないためaddItemDecoration
で区切り線を表示しています。
おわりに
以上で実装部分は終わりです。あとは実行すれば最初の画像と同じようにリストが表示されるはずです。 また、実際に動作するサンプルをGitHubに上げてあります。こちらも合わせて確認ください。
今回はRecyclerViewを実装し表示しました。しかし、このままではタップしても何も起こりません。 そこで次はクリックリスナーの実装とスワイプの処理実装について紹介したいと思います。