#今回やること
今更だけど kotlin でRecyclerViewを実装する。(自分用の備忘録としてほしかった)
クリックイベント処理の記事が少なかったのでタップしたらトーストを表示するのものを作ってみる。
これ↓!
#RecyclerViewの配置
android studio のパレットペインを使って Containersの中にある RecyclerViewをレイアウトに追加する。ドラッグしたらプロジェクトにRecyclerViewが追加され依存関係とかも最新のものが自動的に追加される。
一応、依存関係
dependencies {
implementation 'androidx.recyclerview:recyclerview:1.1.0'
}
レイアウトファイル
<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/simpleRecyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
#RecyclerViewの中身
画像とテキストだけの簡単なレイアウト
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="@android:color/white"
android:elevation="4dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/sampleImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:srcCompat="@mipmap/ic_launcher_round" />
<TextView
android:id="@+id/sampleTxt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="TextView"
android:textSize="30sp" />
</LinearLayout>
elevation
つけとけばいい感じに影をつけてくれる。(※minSdkVersion:21以上必須)
#アダプターをつくる
RecyclerView.Adapter
を継承してつくる
//// customListはrecyclerViewのコンテンツとしてに表示するString配列のデータ
class CustomAdapter(private val customList: Array<String>) : RecyclerView.Adapter<CustomAdapter.CustomViewHolder>(){
// ViewHolderクラス(別ファイルに書いてもOK)
class CustomViewHolder(val view: View): RecyclerView.ViewHolder(view) {
val sampleImg = view.sampleImg
val sampleTxt = view.sampleTxt
}
// getItemCount onCreateViewHolder onBindViewHolderを実装
// 上記のViewHolderクラスを使ってViewHolderを作成
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val item = layoutInflater.inflate(R.layout.recyclerview_item, parent, false)
return CustomViewHolder(item)
}
// recyclerViewのコンテンツのサイズ
override fun getItemCount(): Int {
return customList.size
}
// ViewHolderに表示する画像とテキストを挿入
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
holder.view.sampleImg.setImageResource(R.mipmap.ic_launcher_round)
holder.view.sampleTxt.text = customList[position]
}
}
#アダプターをセット
作ったアダプターをrecyclerViewにセットする
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
/// 表示するテキスト配列を作る [テキスト0, テキスト1, ....]
val list = Array<String>(10) {"テキスト$it"}
val adapter = CustomAdapter(list)
val layoutManager = LinearLayoutManager(this)
// アダプターとレイアウトマネージャーをセット
simpleRecyclerView.layoutManager = layoutManager
simpleRecyclerView.adapter = adapter
simpleRecyclerView.setHasFixedSize(true)
}
}
ここまで出来たらとりあえずrecyclerViewでコンテンツの表示はできているはず。ここからクリックイベントを実装していく。
#リスナーを作る
ボタンにクリックリスナーをつけるみたいに出来ないのでカスタムリスナーを作ってあとで実装する。
先ほどのCustomAdapter.kt
を以下のように修正加筆する。
//// customListはrecyclerViewのコンテンツとしてに表示するString配列のデータ
class CustomAdapter(private val customList: Array<String>) : RecyclerView.Adapter<CustomAdapter.CustomViewHolder>(){
// リスナー格納変数
lateinit var listener: OnItemClickListener
// ViewHolderクラス(別ファイルに書いてもOK)
class CustomViewHolder(val view: View): RecyclerView.ViewHolder(view) {
val sampleImg = view.sampleImg
val sampleTxt = view.sampleTxt
}
// getItemCount onCreateViewHolder onBindViewHolderを実装
// 上記のViewHolderクラスを使ってViewHolderを作成
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val item = layoutInflater.inflate(R.layout.recyclerview_item, parent, false)
return CustomViewHolder(item)
}
// recyclerViewのコンテンツのサイズ
override fun getItemCount(): Int {
return customList.size
}
// ViewHolderに表示する画像とテキストを挿入
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
holder.view.sampleImg.setImageResource(R.mipmap.ic_launcher_round)
holder.view.sampleTxt.text = customList[position]
// タップしたとき
holder.view.setOnClickListener {
listener.onItemClickListener(it, position, customList[position])
}
}
//インターフェースの作成
interface OnItemClickListener{
fun onItemClickListener(view: View, position: Int, clickedText: String)
}
// リスナー
fun setOnItemClickListener(listener: OnItemClickListener){
this.listener = listener
}
}
#リスナーの実装
MainActivity.kt
で実装する
class MainActivity : AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
/// 表示するテキスト配列を作る [テキスト1, テキスト2, ....]
val list = Array<String>(10) {"テキスト$it"}
val adapter = CustomAdapter(list)
val layoutManager = LinearLayoutManager(this )
// アダプターとレイアウトマネージャーをセット
simpleRecyclerView.layoutManager = layoutManager
simpleRecyclerView.adapter = adapter
simpleRecyclerView.setHasFixedSize(true)
// インターフェースの実装
adapter.setOnItemClickListener(object:CustomAdapter.OnItemClickListener{
override fun onItemClickListener(view: View, position: Int, clickedText: String) {
Toast.makeText(applicationContext, "${clickedText}がタップされました", Toast.LENGTH_LONG).show()
}
})
}
}
匿名オブジェクト作って渡したりちょっと見ずらいとこあるけど完成。