/* 본 게시물은 ' ' 의 내용을 토대로 작성되었습니다. */
참고 자료
[RecyclerView에 View Binding 적용하기] : https://cliearl.github.io/posts/android/viewbinding-recyclerview/
[RecyclerView 클릭 이벤트 적용하기] : https://yunaaaas.tistory.com/57
#CardView RecyclerView
Dependency 추가
android {
viewBinding {
enabled = true
}
}
dependencies {
implementation 'androidx.cardview:cardview:1.0.0'
}
MainActivity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.cardviewtest.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
var recyclerView = binding.recyclerviewMain
var layoutManager = LinearLayoutManager(this).apply {
this.orientation = LinearLayoutManager.HORIZONTAL
}
recyclerView.layoutManager = layoutManager
val customAdapter = CustomAdapter()
recyclerView.adapter = customAdapter
}
}
- LinearLayoutManager.HORIZONTAL : RecyclerView의 스코롤을 가로 방향으로 설정한다.
CardData
data class CardData(val title: String, val detail: String, val image: Int) : Serializable
- 카드에 들어갈 정보를 담을 데이터 클래스이다. Adapter에서 DetailActivity로 Intent을 이용해 넘기기 위해 Serializable을 상속 받았다.
CustomAdapter
import android.content.Intent
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.cardviewtest.databinding.CardLayoutBinding
class CustomAdapter : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
val cardDataList : ArrayList<CardData> = arrayListOf(
CardData("one","Item one", R.drawable.beach),
CardData("two","Item two", R.drawable.wave),
CardData("three", "Item three", R.drawable.young_woman),
CardData("four", "Item four", R.drawable.young_woman),
CardData("five", "Item five", R.drawable.beach)
)
override fun onCreateViewHolder(parent: ViewGroup, position: Int): ViewHolder {
val binding = CardLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
class ViewHolder(binding: CardLayoutBinding) : RecyclerView.ViewHolder(binding.root){
val itemTitle: TextView = binding.itemTitle
val itemImage: ImageView = binding.itemImage
val itemDetail: TextView = binding.itemDetail
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.itemTitle.text = cardDataList[position].title
holder.itemDetail.text = cardDataList[position].detail
holder.itemImage.setImageResource(cardDataList[position].image)
holder.itemView.setOnClickListener{
// Toast.makeText(it.context,"클릭", Toast.LENGTH_SHORT).show()
val data = cardDataList[position]
val intent = Intent(holder.itemView.context, DetailActivity::class.java).apply {
putExtra("data", data)
}
holder.itemView.context.startActivity(intent)
}
}
override fun getItemCount(): Int {
return cardDataList.size
}
}
- binding : ViewBinding을 이용해 card_layout.xml 과 바인딩을 한다.
- holder.itemView 에 ClickListener를 달아 클릭 시 DetailActivity를 실행한다.
DetailActivity
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.example.cardviewtest.databinding.ActivityDetailBinding
class DetailActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val data = intent.getSerializableExtra("data") as CardData
val binding = ActivityDetailBinding.inflate(layoutInflater).apply {
this.detailImageView.setImageResource(data.image)
this.detailTitle.text = data.title
this.detailDetail.text = data.detail
}
setContentView(binding.root)
}
}
- Intent로 Serializable 객체를 넘겨받을 때는 .getSerializableExtra()를 사용한다.
Xml file
1. activity_main.xml
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.recyclerview.widget.RecyclerView>
</androidx.constraintlayout.widget.ConstraintLayout>
2. activity_detail.xml
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/detail_detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="44dp"
android:text="TextView"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/detail_title" />
<ImageView
android:id="@+id/detail_imageView"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="136dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
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"
android:layout_marginTop="40dp"
android:text="TextView"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/detail_imageView" />
</androidx.constraintlayout.widget.ConstraintLayout>
3. card_layout_xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/card_view"
android:layout_margin="5dp"
card_view:cardBackgroundColor="#81C784"
card_view:cardCornerRadius="12dp"
card_view:cardElevation="3dp"
card_view:contentPadding="4dp"
>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/item_image"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_title"
android:layout_toEndOf="@+id/item_image"
android:layout_toRightOf="@id/item_image"
android:layout_alignParentTop="true"
android:textSize="30sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/item_detail"
android:layout_toEndOf="@+id/item_image"
android:layout_toRightOf="@+id/item_image"
android:layout_below="@+id/item_title">
</TextView>
</RelativeLayout>
</androidx.cardview.widget.CardView>
실행결과
#궁금한 점
Adapter에서 activity context를 받지 말고 activity에서 클릭 이벤트를 실행할 수 없을까?
[RecyclerView 클릭 이벤트 적용하기] : https://yunaaaas.tistory.com/57
interface OnClickListener를 이용하여 가능.
itemView.context를 이용해도 액티비티를 실행할 수 있음.
관련글
[RecyclerView 더 잘 쓰기] : https://gamjatwigim.tistory.com/120
1. recyclerView 이동 버튼 추가
관련글
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
//...
binding.goFirstBtn.setOnClickListener {
recyclerView.smoothScrollToPosition(0)
}
binding.goMidBtn.setOnClickListener {
recyclerView.smoothScrollToPosition(customAdapter.cardDataList.size / 2)
}
binding.goLastBtn.setOnClickListener {
recyclerView.smoothScrollToPosition(customAdapter.cardDataList.size - 1)
}
}
}
실행 결과
반응형