1. RecyclerView
- 리스트 형태의 데이터를 표시하는데 사용되는 위젯
- 여러 아이템을 스크롤 가능한 리스트로 표현하며, 많은 아이템을 효율적으로 관리하고 보여주는 역할
- 한정적인 화면에 많은 데이터를 넣을 수 있는 View
- View를 재활용해서 사용한다는 특징
2. RecyclerView 사용법
- Adapter
- 데이터 테이블을 목록 형태로 보여주기 위해 사용
- 데이터와 recyclerview 사이의 통신을 위한 연결체
- ViewHolder
- 화면에 표시될 데이터나 아이템들을 저장하는 역할
- 스크롤 해서 위로 올라간 View를 재활용하기 위해서 이 View를 기억하고 있는 역할
3. 활용 예제
활용 1. 리사이클러 뷰를 이용하여 아래의 화면과 같이 만들기
① 모델 객체 만들기
//Profiles.kt
class Profiles(val gender:Int, val name:String, val age:Int, val job:String)
② 가공 받을 형식.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="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/iv_profile"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/woman" />
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:text="이름"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="@id/iv_profile"
app:layout_constraintTop_toTopOf="@id/iv_profile" />
<TextView
android:id="@+id/tv_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="20"
android:textColor="#F44336"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="@id/tv_name"
app:layout_constraintTop_toTopOf="@id/tv_name" />
<TextView
android:id="@+id/tv_job"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:text="직업"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@id/iv_profile"
app:layout_constraintStart_toStartOf="@id/tv_name" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
③ RecyclerView.Adapter 연결 : 데이터 전체를 관리
③-① ViewHolder 연결 : recyclerview의 아이템 하나하나를 관리
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
class ProfileAdapter(val profileList:ArrayList<Profiles>) //Profiles를 리스트화
: RecyclerView.Adapter<ProfileAdapter.CustomViewHolder>() { //RecyclerView.Adapter 속성을 상속
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ProfileAdapter.CustomViewHolder {
TODO("Not yet implemented")
}
override fun onBindViewHolder(holder: ProfileAdapter.CustomViewHolder, position: Int) {
TODO("Not yet implemented")
}
override fun getItemCount(): Int {
TODO("Not yet implemented")
}
//ViewHolder
class CustomViewHolder {
}
}
④-① 뷰 홀더 구현
//뷰를 연결할 때 사용
/*
홀더의 생성자에 아이템 레이아웃을 inflate 한 레이아웃 클래스로 두었지만,
class CustomViewHolder(itemView: View):RecyclerView.ViewHolder(itemView) {
val gender = itemView.findViewById<ImageView>(R.id.iv_profile)
val name = itemView.findViewById<TextView>(R.id.tv_name)
val age = itemView.findViewById<TextView>(R.id.tv_age)
val job = itemView.findViewById<TextView>(R.id.tv_job)
}
여러개의 데이터를 findViewById()를 통해 item을 매치 시킨다면 Hight Cost,
그렇기 때문에 뷰 객체를 ViewHolder에 보관함으로써 findViewById()와 같은 반복적인
호출 메소드를 줄여 속도 개선
*/
class MyViewHolder(private var binding:ListItemBinding):RecyclerView.ViewHolder(binding.root){
//list_item.xml > ListItemBinding
val gender = binding.ivProfile
val name = binding.tvName
val age = binding.tvAge
val job = binding.tvJob
}
④-② 기술 구현
- onCreateViewHolder : Viewholder을 새로 만들때 마다 호출
- ViewHolder와 연결된 view 생성 및 초기화하고, 데이터에 바인딩 된 상태가 아니기 때문에 뷰의 콘텐츠는 채우지 않음
- 3개의 인자를 받는 inflate() 사용
- 각각의 홀더가 부분부분 쓰여지기 때문에 개별 아이템이 view의 정보와 함께 목록 일부에 표시
- param1 : LayoutInflater를 넘기는 것이 없기 때문에 LayoutInflater.from(parent.context)를 사용하여 ViewGroup과 연결된 엑티비티의 context 가지고 옴
- param2 : parent
- param3 : false
- 4주차_ SNS 앱 2. LayoutInflater (tistory.com) 참고
override fun onCreateViewHolder(parent: ViewGroup,viewType: Int)
: ProfileAdapter.CustomViewHolder {
val binding = ListItemBinding.inflate(LayoutInflater.from(parent.context),parent,false)
return CustomViewHolder(binding)
//View를 생성하고 ViewHolder에 View를 전달
}
/*
binding 미사용 시,
override fun onCreateViewHolder(parent: ViewGroup,viewType: Int)
: ProfileAdapter.CustomViewHolder {
val binding = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
return CustomViewHolder(binding)
}
*/
- onBindViewHolder : ViewHolder를 데이터와 연결할 때 호출
- getItemCount : 데이터 항목의 총 개수를 반환
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class ProfileAdapter(val profileList:ArrayList<Profiles>)
: RecyclerView.Adapter<ProfileAdapter.CustomViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup,viewType: Int)
: ProfileAdapter.CustomViewHolder {
val binding = ListItemBinding.inflate(LayoutInflater.from(parent.context),parent,false)
return CustomViewHolder(binding)
}
override fun onBindViewHolder(holder: ProfileAdapter.CustomViewHolder, position: Int) {
holder.gender.setImageResource(profileList.get(position).gender)//현재 클릭한 포지션 위치
holder.name.text = profileList.get(position).name
holder.age.text = profileList.get(position).age.toString()
holder.job.text = profileList.get(position).job
}
override fun getItemCount(): Int {
return profileList.size
}
//코드량 줄일 때: override fun getItemCount() = profileList.size
class MyViewHolder(private var binding:ListItemBinding):RecyclerView.ViewHolder(binding.root){
val gender = binding.ivProfile
val name = binding.tvName
val age = binding.tvAge
val job = binding.tvJob
}
}
⑤ 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">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_profile"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
⑥ ActivityMain.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val profileList = arrayListOf(
Profiles(R.drawable.man, "김철수",20, "의사"),
Profiles(R.drawable.woman, "김영희", 22, "간호사"),
Profiles(R.drawable.man, "박민수",35, "변호사"),
Profiles(R.drawable.woman, "김수영", 25, "조무사"),
Profiles(R.drawable.man, "박영수",20, "세무사"),
Profiles(R.drawable.woman, "한소의", 36, "회계사"),
Profiles(R.drawable.man, "박철민",35, "개발자")
)
binding.rvProfile.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
//리사이클러뷰의 레이아웃 구성 방법
binding.rvProfile.setHasFixedSize(true)
//리사이클러뷰 성능 개선 방안
binding.rvProfile.adapter = ProfileAdapter(profileList)
/*
val adapter = ProfileAdapter(profileList)
binding.rvProfile.adapter = adapter
binding.rvProfile.layoutManager = LinearLayoutManager(this)
*/
}
}
- layoutManager을 MainActivity에서 설정할 수 있지만 activity_main.xml 에서도 가능
'Android' 카테고리의 다른 글
Android Studio_ 7. View binding (0) | 2024.03.27 |
---|---|
Android studio_ Values Resource File 사용 (0) | 2024.03.26 |
Android studio_ 5. Shared Preferences (0) | 2024.02.21 |
Android studio_ 4. NavigationView (1) | 2024.02.13 |
Android studio_ 3. ListView, GridView (1) | 2024.02.09 |