概要
Recycler Viewはリスト表示の基本パターン。ここでは、RecyclerViewの型を理解したことをまとめる。
ついで、Fragment + ViewModelで最単純なアプリを作成する。ViewModelはここでは使はない。
RecyclerViewの全体像
RecyclerViewの型の全体像は下図のとほり。クラス名やファイル名は、後に使ふプログラムに合はせてゐる。
レイアウト
図中右側の破線の枠を入れ物として、図中左側の一行ぶんのレイアウトを 順にはめ込んでゆく。この仕組みと、その入れ物が RecyclerView。
LayoutManager
破線の入れ物に、各行をどのようにはめ込んで行くかを決めるのが LayoutManager。通常は、それを継承する LinearLayoutManagerをもちゐる場合が多い。中身を一列または一行に並べる。生成するときに、VERTCALかHORIZONTALを指定する。
ViewHolder
一行ごとのレイアウトに表示するデータを保持する。
Adapter
3つのコールバック関数を用意して、システムからの求めに応じて動作する。コールバック関数は次のとほり。
| onCreateViewHolder | 一行ぶんのレイアウトを RecyclerViewに送り込むことと、その一行に対応する ViewHolderの生成をおこなふ。 |
| getItemCount | 表示するデータ全数の個数を返す |
| onBindViewHolder | 引数で受け取つた表示番目とそのViewHolderを用ひて、一行分の表示のViewを作る。 |
仕様
以上の理解のもと、次の仕様のRecyclerViewサンプルアプリケーションを作る。
- MainFragment のレイアウトとしてmain_fragment.xmlを持ち、その中に RecyclerViewを持つ。
- 縦にスクロールする50行の文字列とする。
- 各行は2つの文字列を TextViewとして持つ。
- 表示する文字列は"AAA"、"BBB"の固定文字列に行番号を附したものとする。
環境
Android Studio: 3.5.3
Kotlin: ver 1.3
プロジェクト生成
プロジェクト生成
以下の通常手順でプロジェクトを生成する。
- Fragment + ViewModel テンプレート選択 → Next
- Configure your projectで以下を設定
- Name: "RecyclerViewTemplate"
- Language: Kotlin
- Use androidx.* artifacts にチェック
- Finish でおわり
以下の5ファイルができていることを確認する。
- man_fragment.xml
- MainFragment.kt
- MainViewModel.kt
- main_activity.xml
- MainActivity.kt
ここではViewModelは使はぬので、MainViewModel.ktは一切編集せぬ。
ファイル一覧
最終的に作成するファイルの一覧は以下の通り。
| ファイル名 | 説明 |
|---|---|
| each_row.xml | 一行分のレイアウト。2つのTextViewを横に並べたものとする。 |
| main_fragment.xml | MainFragmentが表示するレイアウト。LinearLayoutとし、その中に、RecyclerView 部品を配置する。 |
| EachRowViewHolder.kt | ViewHolder。一行分のViewを保持する。RecyclerVIew.ViewHolderを継承する。 |
| CustomAdapter.kt | Adapter。所定の最低限の三つの関数を overrideする。その中で、各行のレイアウトをRecyclerVIewに吹込み(inflate)、ViewHolderの実体を生成し、各行に表示するデータをViewHolderが持つ各行の中のViewにくべる。 |
| MainActivity.kt | 自動生成される。編集しない。Fragmentの入れ物として機能する。 |
一行分のレイアウトの作成 - each_row.xml
ファイル生成
一行ぶんのレイアウトはLinearLayout (horizontal)とし、その中に TextViewを2つ入れることにする。Designエディタで次の手順で作成する。- app → res → layout → 右クリック New → Layout resource file を選択
- New Resource Fileダイアログで以下を設定
- File name: each_row
- Root element: LinearLayout
- OK
ファイル編集
一行に2つの TextViewを並べるレイアウトにする。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
- 3行目:包含する部品を横に並べるので horizontal を指定。
- 5行目:heightを"match_parent"から"wrap_content"に変へる。かうせぬと、一行が画面縦一杯に広がる。
- 8行目、14行目:idを textView1, textView2 とする。
- 11行目、17行目:横に並べた部品を均等に配置するのでそれぞれ同じ数字を設定。
RecyclerView の配置 - main_fragment.xml
ファイル編集
- はじめからある TextView "MainFragment"を削除
- Paletteから Containers → RecyclerView を選択し 貼り付ける。
- IDは "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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.MainFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="1dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 11行目:idは recyclerVIew とする
ViewHolder クラスの作成 - EachRowViewHolder.kt
ファイル 生成
一行ぶんのレイアウトとデータを保持するクラスを作る。- app → java → com... → 右クリック → New → Kotlin FIle/Class 選択
- New Resource Fileダイアログで以下を設定
- File name: EachRowViewHolder
- Kind: Class
- OK
ファイル編集
生成した EachRowVIewHolder.ktを以下のやうにする。import android.view.View
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.each_row.view.*
class EachRowViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val rowView1 = itemView.textView1
val rowView2 = itemView.textView2
}
- 5行目:RecyclerVIew.ViewHolderを継承する。パラメターの itemViewは、一行分のレイアウトの each_row.xml。
- 6行目、7行目: 文字列のViewへの参照を保持する変数を用意。
Adapter クラスの作成 - MainFragment.kt
ファイル生成
Adapterクラスを定義する- app → java → com... → 右クリック → New → Kotlin FIle/Class 選択
- New Resource Fileダイアログで以下を設定
- File name: CustomAdapter
- Kind: Class
- OK
ファイル編集
コードは以下のやうになる。3つのコールバック関数を定義する。 Classのコンストラクタは、ここでは単純を旨とし設定しない。class CustomAdapter(): RecyclerView.Adapter() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EachRowViewHolder { val layoutInflater = LayoutInflater.from(parent.context) val view = layoutInflater.inflate(R.layout.each_row, parent, false) val viewHolder =EachRowViewHolder(view) return viewHolder } override fun getItemCount(): Int { return 50 } override fun onBindViewHolder(holder: EachRowViewHolder, position: Int) { holder.rowView1.text = "AAA" + position.toString() holder.rowView2.text = "BBB" + position.toString() } }
- 1行目:RecyclerView.Adapterの派生としてゐる
- 3行目〜8行目: コールバック関数の onCreateViewHolderの定義。
- 10行目〜12行目: コールバック関数の getItemCountの定義。固定値50としてゐる。
- 14行目〜16行目:コールバック関数の onBindViewHolder の定義。引数で渡された positionの番号と固定文字列を、引数で渡された ViewHolderの中の変数 rowView (each_row.xmlで定義された textInRow)の中の rowViewに格納してゐる。
MainFragment - MainFragment.kt
最後に、MainFragmentを編集する。- RecyclerViewの送り込み(inflate)、
- Adapterの実体の生成、
- LayoutManagerの実体の生成、
- それら実体を RecyclerViewに格納する。
class MainFragment : Fragment() {
companion object {
fun newInstance() = MainFragment()
}
private lateinit var viewModel: MainViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val view = inflater.inflate(R.layout.main_fragment, container, false)
val adapter = CustomAdapter()
val recyclerView = view.findViewById(R.id.recyclerView)
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(context,LinearLayoutManager.VERTICAL, false)
return view
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
// TODO: Use the ViewModel
}
ビルドと動作確認
ビルドして動作確認する。
(了)
0 件のコメント:
コメントを投稿