[Android/Kotlin] RecyclerView 아이템 클릭 이벤트

핸디·2021년 8월 1일
0

안드로이드

목록 보기
6/9

RecyclerView의 리스트에서 아이템을 클릭했을 때 상세페이지로 넘어가도록 클릭이벤트를 작성해보자

1. 넘어갈 이벤트랑 layout만들기

DetailActivity.kt

package com.example.bookapp

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.room.Room
import com.bumptech.glide.Glide
import com.example.bookapp.databinding.ActivityDetailBinding
import com.example.bookapp.model.Book
import com.example.bookapp.model.Review

class DetailActivity :AppCompatActivity(){

    private lateinit var binding: ActivityDetailBinding
    private lateinit var db:AppDatabase

    override fun onCreate(savedInstanceState: Bundle?) {
        binding= ActivityDetailBinding.inflate(layoutInflater)
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

    }
}

activity_detail.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ScrollView
        android:layout_width="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_height="wrap_content">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/titleTextView"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:textSize="24sp"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                android:layout_margin="16dp"
                app:layout_constraintTop_toTopOf="parent"/>

            <ImageView
                android:id="@+id/coverImageView"
                android:layout_width="300dp"
                android:layout_height="300dp"
                app:layout_constraintTop_toBottomOf="@id/titleTextView"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"/>

            <TextView
                android:id="@+id/descriptionTextView"
                android:textSize="16sp"
                android:layout_width="0dp"
                android:layout_margin="16dp"
                android:layout_height="wrap_content"
                app:layout_constraintTop_toBottomOf="@id/coverImageView"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"/>
            
            <EditText
                android:id="@+id/reviewEditText"
                app:layout_constraintTop_toBottomOf="@id/descriptionTextView"
                android:layout_width="0dp"
                android:layout_height="300dp"
                app:layout_constraintBottom_toTopOf="@id/saveButton"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"/>

            <Button
                android:id="@+id/saveButton"
                android:layout_width="0dp"
                android:text="저장하기"
                android:layout_height="wrap_content"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"/>





        </androidx.constraintlayout.widget.ConstraintLayout>

    </ScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>

2. MainAcitivity에서 정보 가져오기 위해 Intent 작성

이 경우에는 MainActivity -> RecyclerView에서 정보를 가져와야한다.

ListView에서는 메인 액티비티 코드에서 setOnClickListener를 통해 각 item별 클릭 처리를 할 수 있었지만, RecyclerView에서는 별도로 클릭 리스너를 생성해주어야 한다. 이 처리는 Adapter에서 람다를 통해 설정해주었다.

BookAdapter.kt 수정해주기

:BookAdapter(itemClickedListener:Book->Unit) 추가하고
bind 안에서도 처리해준다.

class BookAdapter(private val itemClickedListener:(Book)->Unit):ListAdapter<Book,BookAdapter.BookItemViewHolder>(diffUtil) {

        fun bind(bookModel:Book){//view와 데이터를 연결시키는 함수-/>뷰에 데이터 넣음
            binding.titleTextview.text=bookModel.title
            binding.descriptionTextView.text=bookModel.description

            binding.root.setOnClickListener {
                itemClickedListener(bookModel)
            }
            Glide
                .with(binding.coverImageView.context) //context가 어댑터에 없다 -> 뷰에 있겠죠?
                .load(bookModel.coverSmallUrl)
                .into(binding.coverImageView)

        }
    }

3. ItemClickedListener는 MainActivity에서 작성

  fun initBookRecyclerView(){
        adapter= BookAdapter(itemClickedListener={
            val intent= Intent(this,DetailActivity::class.java)
            intent.putExtra("bookModel",it) **
            startActivity(intent)
        })

        binding.bookRecyclerView.layoutManager=LinearLayoutManager(this)
        binding.bookRecyclerView.adapter=adapter
    }

** putExtra에 클래스전체를 넣어서 가져오려면 사전작업이 필요하다.

1) gradle.app에 다음 추가

androidExtensions {
    experimental = true
}
//원래는 plugin: kotlin-parcelize인데 오류뜸..ㅠ구글링으로 바꾼거

2) 가져오려는 data class에 @parcelize, :Parcelable추가

@Parcelize
data class Book (
    @SerializedName("itemId")val id:Long, //서버에서는 itemid라는 값을,  app에선 id라는 값으로
    @SerializedName("title")val title:String,
    @SerializedName("description")val description:String,
    @SerializedName("coverSmallUrl")val coverSmallUrl:String

):Parcelable

4. DetailActivity에서 받아오는 작업

class DetailActivity :AppCompatActivity(){

    .
    .

    override fun onCreate(savedInstanceState: Bundle?) {
        binding= ActivityDetailBinding.inflate(layoutInflater)
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

       .
       .

        //리사이클러뷰에 있는 데이터 가져와야됨 -> bookadapter

        ** val model=intent.getParcelableExtra<Book>("bookModel")

        binding.titleTextView.text=model?.title.orEmpty()
        binding.descriptionTextView.text=model?.description.orEmpty()

        Glide.with(binding.coverImageView.context)
            .load(model?.coverSmallUrl.orEmpty())
            .into(binding.coverImageView)

이 작업을 마치면 RecyclerView에 있는 아이템을 눌렀을때 상세페이지로 이동해 내용이 출력된다!

📌참고

https://blog.yena.io/studynote/2017/12/07/Android-Kotlin-RecyclerView2.html
https://yunaaaas.tistory.com/57

0개의 댓글