[Android / Kotlin] RecyclerView item 클릭 시 화면 전환

16300 단어 androidandroid

이미 Adapter는 구현되어 있다고 가정하고 진행합니당


👆 준비물

NoticeAdapter
NoticeDTO
NoticeDetailActivity (item 클릭시 띄울 액티비티)


🔨 build.gradle 의존성 추가

Module단위 build.gradle 파일을 열어 plugins와 android에 아래 라인을 추가해주자!

plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-android-extensions'
}
android {
    androidExtensions {
        experimental true
    }
}

뒤에서 설명하겠지만 Parcelize를 사용하기 위해 추가해준 부분이다.


📂 NoticeAdapter.kt

어댑터에서는 ViewHolder에 몇 줄만 추가해주면 된다.

inner class NoticeViewHolder(val binding: ItemNoticeBinding): RecyclerView.ViewHolder(binding.root) {
    fun bind(item: NoticeDTO) {
        binding.notice = item
}

↑ 조촐한 원본 코드

inner class NoticeViewHolder(val binding: ItemNoticeBinding): RecyclerView.ViewHolder(binding.root) {
    private val context = binding.root.context

    fun bind(item: NoticeDTO) {
        binding.notice = item
        itemView.setOnClickListener {
            val intent = Intent(context, NoticeDetailActivity::class.java)
            intent.putExtra("data", item);
            intent.run { context.startActivity(this) }
        }
    }
}

↑ 클릭리스너를 추가해준 코드


🤔#1
클릭 후 띄울 액티비티에 정보를 넘겨주기 위해 Intent를 사용한다. Intent의 파라미터로 context가 필요한데, 어댑터에서 context는 어떻게 사용해야 할까?
→ 모든 뷰에는 context가 담겨 있으므로 그것을 사용하면 된다. private val context = binding.root.context 요렇게!


🤔#2
intent에 담아 넘길 수 있는 데이터의 기본타입은 다음과 같이 한정되어 있다. DataDTO, 즉 우리가 임의로 만든 data class 형태의 데이터를 넘겨주려면 어떻게 해야 할까?
직렬화를 사용한다. Serializable, Parcelable, Parcelize의 세 가지 방법으로 이를 달성할 수 있다.

  • Serializable은 사용이 간편하지만 속도가 굉장히 느리다.
  • Parcelable은 그보다 빠르지만 필요한 코드를 모두 개발자가 구현해줘야 하기 때문에 간단한 값을 넘겨주는것 치고는 너무 작성해야 할 코드가 많다.
  • Parcelize은 Serializable의 간편성과 Parcelable의 성능을 둘 다 잡은 방법이다. ✅ 너로 정했다~!

📂 NoticeDTO

@Parcelize
data class NoticeDTO(
    @SerializedName("category") val category: String,
    @SerializedName("title") val title: String
) : Parcelable

Parcelable을 적용해 보자! data class의 기존 코드에 @Parcelize : Parcelable을 추가해준다.


📂 NoticeDetailActivity

class NoticeDetailActivity : AppCompatActivity() {

    private lateinit var binding: ActivityNoticeDetailBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityNoticeDetailBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val data = intent.getParcelableExtra<NoticeDTO>("data")
        
        binding.detailCategory.text = data!!.category
        binding.detailTitle.text = data!!.title

    }
}

item 클릭시 띄울 액티비티다. intent.getParcelableExtra<NoticeDTO>("data")로 데이터를 넘겨받고 textView에 적용해주었다.

activity_notice_detail.xml

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <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=".activity.NoticeDetailActivity"
        android:padding="20dp">

        <TextView
            android:id="@+id/detail_category"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/detail_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/detail_category" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

끄읏~!


참고
Tistory | 정리하다
Tistory | yoo.dev
Tistory | 개발일지

좋은 웹페이지 즐겨찾기