複数の似たようなデータを表示する場合にはリスト形式のViewを使うのが一般的です。
今回はそのリスト形式のViewをどのように扱うかをやっていきたいと思います。
流れ
- Listを表示する
Activity
を追加します。
- レイアウトにリストの元になるRecyclerViewを置きます
- RecyclerViewにリストを表示するための
Adapter
を用意する
- (リストに表示するデータを用意する)
- 用意したAdapterを
RecyclerView
にセットしてリストを表示する
この流れでいきます。
目指すリストは下の通りです。
シンプルな文字だけどリストです。
Activityを追加
特に難しいことはしませんが一応。
Empty Activity
を作り今回は名前は SimpleStringListActivity
としました。
レイアウトファイルにRecyclerViewを置く
Androidでリスト表示をするには RecyclerVIew
を使います。
まずはレイアウトファイルに配置してみましょう。
1
2
3
4
5
6
7
8
9
10
|
<?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="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
|
RecyclerViewはサポートライブラリーで追加されたViewです。
RecyclerViewで表示するレイアウトを作る
リストとして表示する主な要素となるレイアウトを作成します。
今回はシンプルなリストを目指すのでTextViewのみ置かれたシンプルなレイアウトファイルを作成します。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp" />
</LinearLayout>
|
今作ったレイアウトがリスト形式でたくさん表示されることになります。
Adapterを用意する
RecyclerViewでリスト形式に要素を表示するには RecyclerView.Adapter<T>
を継承したAdapterを用意する必要ががります。
必要最低限なAdapterを書いてみたのでそれを元に何を実装する必要があるか確認してみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
package wacode.yamada.yuki.nempaymentapp.view.adapter
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import wacode.yamada.yuki.nempaymentapp.R
class SimpleStringAdapter(private val context: Context, private val items: List<String>) : RecyclerView.Adapter<SimpleStringAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(context)
val view = inflater.inflate(R.layout.view_simple_string, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val text = items[position]
holder.textView.text = text
}
override fun getItemCount(): Int {
return items.size
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var textView: TextView = itemView.findViewById(R.id.textView)
}
}
|
クラス宣言部
上でも言いましたが、RecyclerViewのAdapterは RecyclerView.Adapter<T>
を継承して作られます。
この T
ですが何が入るかというと RecyclerView.ViewHolder
をを継承したクラスが入ります。
ViewHolderの説明は後程するとして、一旦継承クラスは RecyclerView.Adapterと認識しておいてください。コンストラクタはRecyclerView.Adapterにはないので必要な値を渡しましょう。今回は簡易的に
Context` と 表示したいStringのリストを渡しました。それぞれインスタンス化時にメンバに代入しています。
ViewHolder
その他メソッドを説明する前に RecyclerView.ViewHolder
について説明しておきましょう。
ViewHolderはviewの状態を保持するサブクラスです。スクロールをした時に処理がもたつかないよう(主にfindViewByIdなど)にいい感じに破棄しないようにしてくれます。
ここにはそれぞれのViewの参照を書きます。
今回の例では
1
2
3
|
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var textView: TextView = itemView.findViewById(R.id.textView)
}
|
ここになります。
RecyclerView.ViewHolder
を継承した ViewHolder
クラスで、メンバにTextViewの参照を持っています。
onCerateViewHolder
onCreateViewHolderでは実際に表示したいViewに対して先ほど作ったレイアウトをViewHolderに実際に代入(というよりインスタンス化)している部分です。
ここで生成されたViewHolderはその後 onBindViewHolder
に向かいます。
ここは行が作られる度に呼び出されます。(1行なら1回 100行あれば100回 表示したい行にViewHolderがなければ何度も呼び出されます)
今回の例では
1
2
3
4
5
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(context)
val view = inflater.inflate(R.layout.view_simple_string, parent, false)
return ViewHolder(view)
}
|
この部分です。
先ほど作ったレイアウトファイル view_simple_string
をインフレートしたものをViewHolderに渡しています。
onBindViewHolder
ここで実際にListを表示するための描画処理を行います。
onCreateViewHolde
で生成されたViewHolderが流れてきて、そのViewに対してデータを渡し期待したレイアウトを実現させる部分です。
ここは行が作られる度ではなく表示される度に呼び出されます。
今回の例では
1
2
3
4
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val text = items[position]
holder.textView.text = text
}
|
このアダプターをインスタンス化したときに渡されたStringリストであるItemsからデータを取り出して、それを表示したいTextViewに渡すことで表示しています。簡単でしょう?
データを用意する
今回は特にローカルDBにあるデータを引っ張ってきたり、APIを叩いてリスト形式のデータを使ったりするわけじゃないので適当なListデータを作っちゃいましょう。
1
2
3
4
5
6
7
|
private fun createDummyData():List<String> {
val list = ArrayList<String>()
list.add("りんご")
list.add("ぶどう")
list.add("さかな")
return list
}
|
AdapterをRecyclerViewにセットする
ここまでに作ったAdapterやデータをついにRecyclerViewにセットして表示してみます。
といっても簡単です。
1
2
3
|
val adapter = SimpleStringAdapter(this,createDummyData())
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = adapter
|
Adapterをインスタンス化
LayoutManagerをRecyclerViewにセット
インスタンス化したアダプターをRecyclerViewにセット
それだけです。
LayoutManager
先ほどは急にLayoutmanagerなるものを出しました。
Viewの配置を決めるを決めるものです。
代表的なのは二つで今回使った LinearLayoutManger
と格子状に並べる GridLayoutmanager
です。
おわりで~す