LoginSignup
45
35

More than 3 years have passed since last update.

[kotlin] RecyclerViewの実装、クリックイベント付き

Last updated at Posted at 2020-01-22

今回やること

今更だけど kotlin でRecyclerViewを実装する。(自分用の備忘録としてほしかった)
クリックイベント処理の記事が少なかったのでタップしたらトーストを表示するのものを作ってみる。
これ↓!

RecyclerViewの配置

android studio のパレットペインを使って Containersの中にある RecyclerViewをレイアウトに追加する。ドラッグしたらプロジェクトにRecyclerViewが追加され依存関係とかも最新のものが自動的に追加される。

一応、依存関係

build.gradle
dependencies {
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
}

レイアウトファイル

activity_main.xml
<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の中身

画像とテキストだけの簡単なレイアウト

recyclerview_item.xml
<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を継承してつくる

CustomAdapter.kt
//// 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にセットする

MainActivity.kt
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を以下のように修正加筆する。

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で実装する

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()
            }
        })
    }
}

匿名オブジェクト作って渡したりちょっと見ずらいとこあるけど完成。

45
35
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
45
35