Android

[안드로이드] 리사이클러뷰를 만들어보자

남드로이드 2022. 1. 14. 23:28

리사이클러뷰

:

용도

구성요소

어댑터
: 리사이클러뷰의 속성을 관리한다
뷰홀더
모델

장단점

사용예제

리사이클러뷰 dependency

build.gradle에 dependency를 추가해준다
https://developer.android.com/jetpack/androidx/releases/recyclerview#kts

dependencies {
    implementation("androidx.recyclerview:recyclerview:1.2.1")
    // For control over item selection of both touch and mouse driven selection
    implementation("androidx.recyclerview:recyclerview-selection:1.1.0")
}

레이아웃을 구성해준다

 

메인 레이아웃에 리사이클러뷰 부분을 그려준다 (activity_main)

<androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/my_recycler_view"
        >
</androidx.recyclerview.widget.RecyclerView>

리사이클러뷰의 각각의 뷰?아이템? 으로사용할 레이아웃을 그려준다 (recyclerview_item)

<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <ImageView
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_margin="30dp"
            >
        </ImageView>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="텍스트입니다..."
            android:textSize="30dp"
            android:layout_gravity="center"
            >
        </TextView>
    </LinearLayout>
</androidx.cardview.widget.CardView>

카드뷰 dependency

아이템을 카드뷰로 쓰고싶으면 dependency를 또 추가해준다
=> 왜카드뷰를 쓰는가??

dependencies {
    implementation("androidx.cardview:cardview:1.0.0")
}

뷰홀더에 연결될 모델을하나 만들어준다

class MyRecyclerViewModel{
    var imageview:String?=null
    var name:String?=null

    constructor(imageview:String, name:String){
        this.imageview = imageview
        this.name = name
    }
}

리사이클러뷰의 속성을 관리할 어댑터를 만들어아한다

먼저 어댑터에 달릴 뷰홀더를 만들어준다

뷰홀더란?
"ListView / RecyclerView 는 inflate를 최소화 하기 위해서 뷰를 재활용 하는데, 이 때 각 뷰의 내용을 업데이트 하기 위해 findViewById 를 매번 호출 해야합니다. 이로 인해 성능저하가 일어남에 따라 ItemView의 각 요소를 바로 엑세스 할 수 있도록 저장해두고 사용하기 위한 객체입니다."
※ inflate? : xml 로 쓰여있는 View의 정의를 실제 VIew 객체로 만드는 것을 말함.

class MyRecyclerViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
    private var myImageView = itemView.myimageview
    private var myText = itemView.mytext

    fun bindViewModel(myRecyclerViewModel: MyRecyclerViewModel){
       this.myText.text = myRecyclerViewModel.txt

        Glide
            .with(App.instance)
            .load("urltest")
            //.centerCrop()
            .placeholder(R.drawable.ic_launcher_background) //url 없을때 대체해서보여줄것
            .into(myImageView);
    }

}

*findViewById 하기싫으면 plugin 추가해준다

plugins {
    id 'kotlin-android-extensions'
}

Glide dependency

뷰홀더에 이미지 박아야하니까 glide 를 사용해야한다
레포추가

allprojects {
    repositories {
        mavenCentral()
    }
}

dependency추가

dependencies {
    implementation 'com.github.bumptech.glide:glide:4.12.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
}

*Context 전역변수화 방법 -> 이거좀더 공부필요
App 클래스하나 만들어준다

class App:Application() {
    companion object{
        lateinit var instance:App
            private set
    }

    override fun onCreate() {
        super.onCreate()
        instance = this
    }
}

Manifest를 약간 수정해준다

 <application
        android:name=".App"
 </application>

뷰홀더 만들었으니,, 이 뷰홀더를 이용한 어댑터를 만들어준다

class MyRecyclerViewAdapter(var modelList:ArrayList<MyRecyclerViewModel>):RecyclerView.Adapter<MyRecyclerViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyRecyclerViewHolder {
        // 연결할 레이아웃설정
        return MyRecyclerViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.recyclerview_item, parent, false)) // 루트에 붙일꺼냐? -> false
    }

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

    // 뷰홀더에 데이터를 연결해주는 함수
    // -> 뷰는 재활용되지만 데이터는 계속해서 새롭게 연결되어야하기 때문
    override fun onBindViewHolder(holder: MyRecyclerViewHolder, position: Int) {
        holder.bindViewModel(this.modelList[position])
    }

}

메인액티비티에서 이를 집합시킨다

리사이클러뷰생성 -> 어댑터설정 -> 데이터바인딩

class MainActivity : AppCompatActivity() {

    private var modelList = ArrayList<MyRecyclerViewModel>()
    private lateinit var myRecyclerViewAdapter:MyRecyclerViewAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        for(i in 1..10){
            var newmodel = MyRecyclerViewModel("imageview", "$i 번째카드")
            this.modelList.add(newmodel)
        }

        //어댑터
        myRecyclerViewAdapter = MyRecyclerViewAdapter(modelList)

        // 뷰 렌더링
        my_recycler_view.apply{
            adapter = myRecyclerViewAdapter
            layoutManager = LinearLayoutManager(this@MainActivity)
        }
    }
}

 


참고
https://www.youtube.com/channel/UCutO2H_AVmWHbzvE92rpxjA
https://developside.tistory.com/88

전체소스
https://github.com/njs8590/RecyclerViewExample