상세 컨텐츠

본문 제목

안드로이드(ANDROID) - 리사이클러뷰(RecyclerView)를 통한 ListView 사용 방법(1)

Android 자료실/기능 개발

by Victorywskim 2020. 3. 30. 18:39

본문

반응형

최근 페이지를 하나 만들면서 리사이클러뷰를 사용할 일이 있었는데 오랜만에 사용해서 그런지 기억이 잘 나지않았다.

그래서 다음에 또 이런 경우가 생기는 것을 방지하기 위해서 사용 방법에 대해 적어보려고 한다.

 

사용 방법은 정말 간단하니 아래 순서에 따라 진행해보길 바란다.

 

1. gradle에 종속성을 추가한다.

dependencies {
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
}

 

2. xml을 통해 레이아웃을 구성한다.

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".main.MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginStart="@dimen/main_margin"
        android:layout_marginEnd="@dimen/main_margin"
        android:layout_gravity="center"
        android:background="@color/light_gray"
        android:gravity="center"
        android:text="@string/main_title"
        android:textColor="@color/black"
        android:textSize="24sp" />

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

</LinearLayout>

 

3. 리사이클러뷰에 연결할 어댑터와 vo를 만든다.

 

- 어댑터

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import wskim.android.utilcollection.R

class UtilListAdapter(private val context: Context) : RecyclerView.Adapter<UtilListAdapter.UtilViewHolder>() {

    var utilList: ArrayList<UtilListItem>? = null
    fun setItemList(utilList: ArrayList<UtilListItem>){
        this.utilList = utilList
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UtilViewHolder {
        return UtilViewHolder(LayoutInflater.from(context).inflate(R.layout.util_list_item, parent, false))
    }

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

    override fun onBindViewHolder(holder: UtilViewHolder, position: Int) {
        val item = utilList!![position]

        holder.utilItemNo.text = (position + 1).toString()
        holder.utilItemTitle.text = item.utilTitle
        holder.utilItemMsg.text = item.utilMsg

//        holder.itemView.layoutParams = RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)

        holder.itemView.setOnClickListener {
            Toast.makeText(context, "클릭 $position", Toast.LENGTH_SHORT).show()
        }
    }

    class UtilViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val utilItemNo: TextView = view.findViewById(R.id.util_item_no)
        val utilItemTitle: TextView = view.findViewById(R.id.util_item_title)
        val utilItemMsg: TextView = view.findViewById(R.id.util_item_msg)
    }
}

 

- item_layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:layout_margin="@dimen/main_margin"
    android:background="@drawable/shape_to_circle_box"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/util_item_no"
        android:layout_width="60dp"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textColor="@color/black"
        android:textSize="16sp" />

    <View
        android:layout_width="1dp"
        android:layout_height="match_parent"
        android:background="@color/dark_gray" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/util_item_title"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_marginStart="5dp"
            android:gravity="center_vertical"
            android:text="타이틀"
            android:textColor="@color/black" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="@color/dark_gray" />

        <TextView
            android:id="@+id/util_item_msg"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_marginStart="5dp"
            android:gravity="center_vertical"
            android:text="설명"
            android:textColor="@color/black" />

    </LinearLayout>
</LinearLayout>

 

- VO

data class UtilListItem(
    var utilTitle: String?,
    var utilMsg: String?
)

 

4. 리사이클러뷰에 어탭터를 연결한다.

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.activity_main.*
import wskim.android.utilcollection.R
import wskim.android.utilcollection.main.adapter.UtilListAdapter
import wskim.android.utilcollection.main.adapter.UtilListItem

class MainActivity : AppCompatActivity() {

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

        val item = UtilListAdapter(this).apply {
            setItemList(getListData())
        }

        util_list.apply {
            // 리스트에 밑줄이 필요하면 아래 주석 제거
//            addItemDecoration(DividerItemDecoration(this@MainActivity, DividerItemDecoration.VERTICAL))
            layoutManager = LinearLayoutManager(this@MainActivity, RecyclerView.VERTICAL, false)
            adapter = item
        }
    }

    // 데이터 입력하기
    private fun getListData() : ArrayList<UtilListItem>{
        val result = ArrayList<UtilListItem>()
        result.add(UtilListItem(
            "유틸1"
        ,"설명 블라블라ddddd"
        ))
        result.add(UtilListItem(
            "유틸2"
            ,"설명 블라블라"
        ))
        result.add(UtilListItem(
            "유틸3"
            ,"설명 블라블라"
        ))
        return result
    }
}

 

5. 리스트가 잘 표시되는지 확인해본다.

앱 실행 화면이다.
리스트 터치 시에도 토스트도 잘 표시된다.

 

위의 소스코드까지가 리사이클러뷰를 사용하기 위한 방법인데 오늘 잠깐 혼란스러운 시간이 있었다.

 

3번의 어탭터 소스코드 중간에 보면 아래와 같이 주석처리 해논 코드가 하나 있다.

//        holder.itemView.layoutParams = RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)

 

이건 리사이클러뷰를 생성할때 동적으로 사이즈를 변경하기 위한 코드인데 리스트를 만들면 계속 사이즈가 아래 이미지와 같이 표시되는 문제가 있었다.

(ㅠ ㅅ ㅠ)...

 

이걸로 삽질을 좀 오래 했는데 알고보니 아래 코드에 문제가 있었다.

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UtilViewHolder {
        return UtilViewHolder(LayoutInflater.from(context).inflate(R.layout.util_list_item, null, false))
}

 

.inflate 뒤에 인자로 layout과 부모 뷰를 입력하도록 되어있는데 부모 뷰가 없으니 뷰의 사이즈를 가늠할수없었고 그래서 xml상의 match_parent가 작동되지 않고 wrap_content 로 뷰가 만들어지는 안타까운 일이 있었다.

어자피 다음에는 복붙으로 작업할거 같아서 뭐 또 다시 만날것 같진 않지만 시간 낭비한게 억울해서 적어보았다...

 

이 작업 외에도 리사이클러뷰에 interface도 붙이고 해야하는데 그런 작업들은 필요 시 작업하고 추가로 포스팅 하도록 하겠다.

 

이것으로 리사이클러뷰에 대한 사용 방법을 마치겠다.

 

반응형

관련글 더보기