본문 바로가기
공부/Android Studio

[Android/Kotlin] Recycler view 사용법

by 웅대 2022. 12. 8.
728x90
반응형

애플리케이션에서 동일한 형식을 가진 여러 개의 데이터를 출력해야 할 때가 있다.

 

예를 들어 특정 사이트의 회원 정보를 출력하여 관리할 때 회원 하나하나마다 레이아웃을 구성하는 것은 비효율적이다.

 

이럴 때 안드로이드 스튜디오의 Recycler view를 사용하면 하나의 레이아웃만 만들어둔다면 자동으로 이 레이아웃에 맞게끔 여러 정보를 출력할 수 있다.

 

간단하게 회원의 이름, 나이, 주소 정보들의 배열을 출력해보겠다.

 

이번 포스팅 역시 view binding을 사용할 예정이다.

https://growth-coder.tistory.com/30

 

[Android/Kotlin] activity와 fragment에서 view binding 사용법

view binding을 사용하면 view에 존재하는 값들에 접근할 수 있다. 이전에는 view에 존재하는 값들에 접근하기 위해서는 해당 ID를 사용해서 findViewById를 사용하였다. 이제는 view binding을 사용하면 쉽게

growth-coder.tistory.com

 

view binding에 대한 자세한 설명은 위 포스팅을 참고하길 바라고 view binding이 세팅된 상태로 시작하겠다.

class MainActivity : AppCompatActivity() {
    lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding=ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
    }
}

view binding 세팅 완료

 

레이아웃 생성

 

recycler_view라는 xml 파일을 만든다.

이름, 나이, 주소의 정보를 표현할 textView 3개를 만들고 각각 아이디를 txt_name, txt_age, txt_address로 정해주었다.

<?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">

    <TextView
        android:id="@+id/txt_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginBottom="16dp"
        android:text="name"
        android:textSize="30dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/txt_age"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/txt_age"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="age"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/txt_address"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/txt_name"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/txt_address"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="address"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/txt_age"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
데이터 클래스 생성

이제 데이터 클래스를 만들 차례이다.

 

유저의 정보들을 보여줘야하므로 당연히 유저의 이름, 나이, 주소 정보가 담겨있는 데이터 클래스를 만들어야한다.

data class User(
    val name:String,
    val age:Int,
    val address:String
)

User라는 데이터 클래스로 이루어진 배열을 어댑터에 넣어서 view에 보여줄 것이다.

 

어댑터 생성

이제 유저들의 정보를 바탕으로 view에 정보들을 보여줄 어댑터를 만들 차례이다.

 

UserAdapter라는 클래스를 만들고 그 안에 holder class를 만들어줘야한다.

 

둘 다 상속을 받아야하는데 아래와 같이 상속을 받으면 된다.

 

또한 어댑터에는 파라미터로 User 데이터 클래스의 배열을 넘겨줘야한다.

class UserAdapter(val array:Array<User>):RecyclerView.Adapter<UserAdapter.Holder>() {
    inner class Holder(val binding: RecyclerViewBinding) : ViewHolder(binding.root) {

    }
}

그리고 Holder의 파라미터 타입은 바인딩이다.

 

xml파일 이름을 recycler_view로 정했으므로 view binding으로 여기에 접근하기 위해서는 파라미터 타입이

 

RecyclerViewBinding이 되어야한다.

 

아마 아래와 같이 오류가 발생할 것이다.

Alt+shift+enter를 누르면 

전부 선택하고 추가해준다.

class UserAdapter(array:Array<User>):RecyclerView.Adapter<UserAdapter.Holder>() {
    inner class Holder(binding: RecyclerViewBinding) : ViewHolder(binding.root) {

    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserAdapter.Holder {
        TODO("Not yet implemented")
    }

    override fun onBindViewHolder(holder: UserAdapter.Holder, position: Int) {
        TODO("Not yet implemented")
    }

    override fun getItemCount(): Int {
        TODO("Not yet implemented")
    }
}

 

 

이제 어댑터 기본 세팅은 마쳤고 코드를 작성해주면 된다.

 

먼저 Holder 클래스에 데이터를 바인딩하는 메소드를 만들어준다.

inner class Holder(val binding: RecyclerViewBinding) : ViewHolder(binding.root) {
    fun dataBinding(user:User){
        binding.txtName.text=user.name
        binding.txtAge.text=user.age.toString()
        binding.txtAddress.text=user.address
    }
}

 

getItemCount함수는 파라미터로 받은 배열의 크기를 반환해준다.

 

override fun getItemCount(): Int {
    return array.size
}

 

onCreateViewHolder에는 Holder에 binding을 담아서 반환해준다.

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserAdapter.Holder {
    val binding = RecyclerViewBinding.inflate(LayoutInflater.from(parent.context),parent,false)
    return Holder(binding)
}

이제 onBindViewHolder에서는 파라미터로 받은 holder의 메소드를 이용하여 데이터를 바인딩해주면 된다.

override fun onBindViewHolder(holder: UserAdapter.Holder, position: Int) {
    holder.dataBinding(array[position])
}

UserAdapter 최종 코드

class UserAdapter(val array:Array<User>):RecyclerView.Adapter<UserAdapter.Holder>() {
    inner class Holder(val binding: RecyclerViewBinding) : ViewHolder(binding.root) {
        fun dataBinding(user:User){
            binding.txtName.text=user.name
            binding.txtAge.text=user.age.toString()
            binding.txtAddress.text=user.address
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserAdapter.Holder {
        val binding = RecyclerViewBinding.inflate(LayoutInflater.from(parent.context),parent,false)
        return Holder(binding)
    }

    override fun onBindViewHolder(holder: UserAdapter.Holder, position: Int) {
        holder.dataBinding(array[position])
    }

    override fun getItemCount(): Int {
        return array.size
    }
}

정보가 보여질 형태도 만들었고 어댑터도 만들었다.

 

이제 메인 액티비티에서 리사이클러뷰를 보여주는 코드를 만들 차례이다.

 

먼저 activity_main.xml에서 리사이클러뷰를 넣어주고 아이디를 recycler_view로 정해준다.

 

MainActivity.kt에서 먼저 임의의 User 배열을 만들어준다.

val arr:Array<User> = arrayOf<User>(
    User("철수",10,"서울"),
    User("민수",14,"대구"),
    User("정수",9,"부산"),
    User("칠수",20,"대전"),
    User("상수",25,"나주")
)

 지금은 임의로 정했지만 실제로는 데이터베이스에서 값을 가져오거나 api를 요청한 값을 받아오게 될 것이다.

 

메인 액티비티에서 바인딩은 전부 세팅을 해놨으므로 코드 두 줄만 추가하면 된다.

binding.recyclerView.layoutManager=LinearLayoutManager(this)
binding.recyclerView.adapter=UserAdapter(arr)

MainActivity 최종 코드

class MainActivity : AppCompatActivity() {
    lateinit var binding: ActivityMainBinding
    val arr:Array<User> = arrayOf<User>(
        User("철수",10,"서울"),
        User("민수",14,"대구"),
        User("정수",9,"부산"),
        User("칠수",20,"대전"),
        User("상수",25,"나주")
    )
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding=ActivityMainBinding.inflate(layoutInflater)
        binding.recyclerView.layoutManager=LinearLayoutManager(this)
        binding.recyclerView.adapter=UserAdapter(arr)
        setContentView(binding.root)

    }
}

다음 포스팅에서는 MVVM 패턴을 사용하여 유저 정보를 받아와 리사이클러뷰에 넣어주는 작업을 해보려한다.

728x90
반응형

댓글