[AOS] RecyclerView

2024. 2. 6. 14:56dev/aos

728x90
반응형

RecyclerView는 여러 아이템을 리스트 형태로 보여주는 뷰이다.

모든 아이템을 한 꺼번에 로드하여 가지고 있는 것이 아닌 필요한 양 만큼 갱신하여 보여주는 것이 특징

RecyclerView를 현재 Compose에서는 좀더 편리하게 구현을 하고 있다고는 하나,

나는 원래 사용하던 구조가 더 명확히 분리되어 있어 이전 방법을 애용한다.

 

언어 : Kotlin

 

 

1. Layout내부에 RecylcerView를 만든다

<LinearLayout>
	<androidx.recyclerview.widget.RecyclerView
    	android:id="@+id/recyclerItemList"
    	...
        
        />

</LinearLayout>

 

 

그럼, 화면에 다음과 같이 생성된다.

 

 

2. RecyclerView에 들어갈 리스트 아이템의 레이아웃을 만든다.

<LinearLayout
	android:orientation="horizontal">
    
    <TextView
    	android:id="@+id/textMessage"
    	...
    />

</LinearLayout>

아이템에 카드를 넣고 리플(Ripple)효과 첨가

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.cardview.widget.CardView
        android:id="@+id/bluetoothCard"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="4dp"
        android:clickable="true"
        app:cardCornerRadius="8dp"
        app:cardElevation="4dp"
        android:focusable="true"
        android:foreground="?attr/selectableItemBackground">

        <TextView
            android:id="@+id/bluetoothDeviceName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="21sp" />

    </androidx.cardview.widget.CardView>
</LinearLayout>

 

 

화면에 보여줄 레이아웃 준비는 끝.

 

코드 작업

- RecyclerView 리스트 내부 아이템들을 관리할 'Adapter' 필요

 

3. Adapter클래스 작업

Adpater 틀

더보기
class FlowersAdapter: RecyclerView.Adapter<FlowersAdapter.FlowerAdapterHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FlowerAdapterHolder {
        TODO("Not yet implemented")
    }

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

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

    inner class FlowerAdapterHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    }
}
class TestAdpater: RecyclerView.Adapter<TestViewHolder>() {
	// 리스트에 표출할 데이터(또는 외부에서 받을 수 있도록 함수 조정)
    val tempData: ArrayList<String> = ArrayList<String>()

	// 리스트 아이템의 갯수를 꼭 명시해주어야 함
	override fun getItemCount(): Int {
    	return tempData.size
    }
    
    // 리스트 아이템의 레이아웃을 입혀주는 함수
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TestViewHolder {
    	val view = LayoutInflater.from(parent.context).inflate(R.layout.item_test, parent, false)
        return TestViewHolder(view)
    }
    
    // 리스트 아이템에 적용될 데이터를 입혀주는 함수
    override fun onBindViewHolder(@NonNull holder: TestViewHolder, position: Int) {
    	// 데이터의 해당 position위치에 적용될 값을 입혀줌
        val text = tempData[position].toString()
    	holder.textMessage.text = text
    }
    
    inner class TestViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
    	// UI레이아웃 초기화
        val textMessage = itemView.findViewById(R.id.textMessage)
        
        // TODO, Button이 있는 경우는 동작을 선언해주기도 함
        // buttonApply.setOnClickListener( ... )
    }
}

 

리스트는 Mutable로 사용하면 더 유연하다.

    private val tempData: MutableList<String> = mutableListOf<String>()

 

그리고 데이터를 추가시 자연스럽게 추가 되는 것은 다음과 같이 notify를 해주면 된다.

    fun add(deviceName: String) {
        NLog.w("BluetoothDevicesADapter.. add.. deviceName:$deviceName, count:$itemCount")
        tempData.add(deviceName)
        notifyItemInserted(tempData.size - 1)
    }

 

 

4. RecyclerView ∽ Adapter 연결

dataBinding 사용

fun init() {
	// adapter 생성 및 연결
	val testAdapter = TestAdapter()
	binding.recyclerItemList.adapter = testAdapter
	
    // LinearManager 설정 : 리스트내 아이템들을 나열하기 위함
    val layoutManager = LinearLayoutManager(context = this)
    layoutManager.orientation = VERTICAL
    binding.recyclerItemList.layoutManager = layoutManager
}

 

 

앞으로는 상황에 맞게 코드를 구성하면 된다.

 


Adapter선언시 바로 클릭이 가능하도록 Interface만들기

position -> 형태로 받을 수 있음

/**
 * Simple RecyclerView adapter
 */
class IntegrationItemAdapter(
    private val items: List<IntegrationType>,
    private val onClick: (Int) -> Unit
) : RecyclerView.Adapter<IntegrationItemAdapter.IntegrationItemViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): IntegrationItemViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(
            R.layout.item_integration_type,
            parent,
            false
        )

        return IntegrationItemViewHolder(view)
    }

    override fun onBindViewHolder(holder: IntegrationItemViewHolder, position: Int) {
        val integrationType = items[position]

        with (holder) {
            title.text = integrationType.name
            image.setImageResource(integrationType.image)

            itemView.setOnClickListener { onClick(position) }
        }
    }

    override fun getItemCount(): Int = items.size

    class IntegrationItemViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val title: TextView = view.findViewById(R.id.title_integration)
        val image: ImageView = view.findViewById(R.id.image_integration)
    }
}
    private fun setIntegrationItems(integratiosList: List<IntegrationType>) {
        integrationsRecyclerView.adapter = IntegrationItemAdapter(integratiosList) { position ->
            onIntegrationClicked(position)
        }
    }
728x90
반응형

'dev > aos' 카테고리의 다른 글

[AOS] Kakao Login  (0) 2024.02.13
[AOS] PackageInfo #move other app  (0) 2024.02.08
[AOS] Timer  (0) 2024.02.06
[AOS] lazy init binding  (0) 2024.02.05
[AOS] Permission  (0) 2024.02.05