[Android / Kotlin] RecyclerView 가로 정렬 / GridLayoutManager

Subeen·2023년 3월 8일
0

Android

목록 보기
7/73
post-thumbnail

안드로이드에서는 RecyclerView와 함께 사용 가능한 LayoutManager 라이브러리 3가지를 제공한다. Recycler의 아이템의 배치와 재사용에 대한 정책을 결정하면 LayoutManager의 종류에 따라 아이템의 배치가 변경되며 LayoutManager 라이브러리 종류는 다음과 같다.

📍 LayoutManager 종류

  • LinearLayoutManager : 수평/수직으로 아이템을 배치한다.
  • GridLayoutManager : 격자 화면으로 아이템을 배치한다.
  • StaggeredGridLayoutManage : 높이가 불규칙한 격자 화면으로 아이템을 배치한다.

📍 LinearLayoutManager: 세로 정렬

📌 LinearLayoutManager를 사용하여 세로 정렬
binding.recyclerView.layoutManager = LinearLayoutManager(this)

💡 자세한 내용은 RecyclerView 세로 정렬 이전 포스팅을 확인해보자

📍 LinearLayoutManager: 가로 정렬

📌 LinearLayoutManager를 사용하여 가로 정렬
binding.recyclerview.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)

💡 두 번째 인자는 레이아웃 방향(HORIZONTAL 또는 VERTICAL)을 의미하며 세 번째 인자는 reverseLayout을 의미한다. reverseLayout을을 true로 설정 시 레이아웃이 끝에서 시작된다.

📍 결과 동영상

👩🏻‍💻 RecyclerView 생성하기

// activity_recycler_view.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>

    <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"
        tools:context=".recyclerview.RecyclerViewActivity">

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

    </LinearLayout>
</layout>

👩🏻‍💻 데이터 클래스 생성하기

// RecyclerModel.kt
class RecyclerModel(
    val image: Int, val title: String, val content: String, val price: String
)

👩🏻‍💻 RecyclerView 아이템 생성하기

// item_rv_horizontal.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="150dp"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/imageArea"
        android:layout_width="150dp"
        android:layout_height="150dp" />

    <TextView
        android:id="@+id/titleArea"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_weight="2"
        android:textColor="@color/black"
        android:textSize="14sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/contentArea"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_weight="1"
        android:textColor="@color/black"
        android:textSize="12sp" />

    <TextView
        android:id="@+id/priceArea"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_weight="1"
        android:textColor="@color/black"
        android:textSize="12sp"
        android:textStyle="bold" />
</LinearLayout>

👩🏻‍💻 Adapter 생성하기

// RecyclerHorizontalAdapter.kt
class RecyclerHorizontalAdapter(val items: MutableList<RecyclerModel>) :
    RecyclerView.Adapter<RecyclerHorizontalAdapter.ViewHolder>() {
    interface onItemClickListener {
        fun onItemClick(position: Int)
    }

    private lateinit var itemClickListener: onItemClickListener

    fun setItemClickListener(itemClickListener: onItemClickListener) {
        this.itemClickListener = itemClickListener
    }

    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): RecyclerHorizontalAdapter.ViewHolder {
        val v =
            LayoutInflater.from(parent.context).inflate(R.layout.item_rv_horizontal, parent, false)
        return ViewHolder(v)
    }

    override fun onBindViewHolder(holder: RecyclerHorizontalAdapter.ViewHolder, position: Int) {
        holder.itemView.setOnClickListener {
            itemClickListener.onItemClick(position)
        }
        holder.bindItems(items[position])
    }

    override fun getItemCount(): Int {
        return items.count()
    }

    inner class ViewHolder(itemView: View) :
        RecyclerView.ViewHolder(itemView) {
        fun bindItems(items: RecyclerModel) {
            val imageArea = itemView.findViewById<ImageView>(R.id.imageArea)
            val titleArea = itemView.findViewById<TextView>(R.id.titleArea)
            val contentArea = itemView.findViewById<TextView>(R.id.contentArea)
            val priceArea = itemView.findViewById<TextView>(R.id.priceArea)

            imageArea.setImageResource(items.image)
            titleArea.text = items.title
            contentArea.text = items.content
            priceArea.text = items.price
        }
    }
}

👩🏻‍💻 RecyclerView에 Adapter 연결하기

class RecyclerViewActivity : AppCompatActivity() {
    lateinit var binding: ActivityRecyclerViewBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_recycler_view)

        initRecycler()
    }

    private fun initRecycler() {
        val itemList = mutableListOf<RecyclerModel>()
        itemList.add(RecyclerModel(R.drawable.item_lv_01, "마리떼 프랑소와 저버", "CLASSIC LOGO CAP beige", "49,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_02, "마리떼 프랑소와 저버", "CLASSIC LOGO WOOL ECO BAG blue", "49,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_03, "마리떼 프랑소와 저버", "COLOR BLOCK SATIN SCRUNCHIE navy", "39,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_04, "마리떼 프랑소와 저버", "CLASSIC LOGO BACKPACK light blue", "159,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_05, "마리떼 프랑소와 저버", "CLASSIC LOGO COLOR BEANIE navy", "49,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_06, "원브릴리언트", "Ivan-OB166-Black", "112,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_07, "시엔느", "Washing Lettering Ball Cap (Navy)", "49,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_08, "마뗑킴", "ACCORDION WALLET IN WHITE", "88,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_09, "마리떼 프랑소와 저버", "CIRCLE LOGO SATIN HAIRBAND ivorye", "29,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_10, "리엔느와르","Dot Toggle Pearl Necklace (2color)", "57,000원"))

        val adapter = RecyclerHorizontalAdapter(itemList)
        binding.recyclerview.adapter = adapter
         binding.recyclerview.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)

        adapter.setItemClickListener(object: RecyclerHorizontalAdapter.onItemClickListener{
            override fun onItemClick(position: Int) {
                Toast.makeText(applicationContext, "RecyclerView: ${itemList[position].title}", Toast.LENGTH_SHORT).show()
            }
        })
    }
}

📍 GridLayoutManager: 격자형 정렬

📌 GridLayoutManager를 사용하여 수직 격자 정렬
binding.recyclerview.layoutManager = GridLayoutManager(this, 2)

💡 수직 GridLayoutManager를 생성하며 두 번째 인자는 열의 개수를 의미한다.

📍 결과 동영상

👩🏻‍💻 RecyclerView 아이템 생성하기

❗️ RecyclerView의 아이템과 Activity 부분만 수정하였으며 그 외는 위에서 사용한 코드를 그대로 사용하였다.

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

    <ImageView
        android:id="@+id/imageArea"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true" />

    <TextView
        android:id="@+id/titleArea"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_weight="2"
        android:textColor="@color/black"
        android:textSize="14sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/contentArea"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_weight="1"
        android:textColor="@color/black"
        android:textSize="12sp" />

    <TextView
        android:id="@+id/priceArea"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_weight="1"
        android:textColor="@color/black"
        android:textSize="12sp"
        android:textStyle="bold" />
</LinearLayout>
  • android:adjustViewBounds="true" : 비율에 맞게 이미지 조정

👩🏻‍💻 RecyclerView에 Adapter 연결하기

// RecyclerViewActivity.kt
class RecyclerViewActivity : AppCompatActivity() {
    lateinit var binding: ActivityRecyclerViewBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_recycler_view)

        initRecycler()
    }

    private fun initRecycler() {
        val itemList = mutableListOf<RecyclerModel>()
        itemList.add(RecyclerModel(R.drawable.item_lv_01, "마리떼 프랑소와 저버", "CLASSIC LOGO CAP beige", "49,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_02, "마리떼 프랑소와 저버", "CLASSIC LOGO WOOL ECO BAG blue", "49,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_03, "마리떼 프랑소와 저버", "COLOR BLOCK SATIN SCRUNCHIE navy", "39,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_04, "마리떼 프랑소와 저버", "CLASSIC LOGO BACKPACK light blue", "159,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_05, "마리떼 프랑소와 저버", "CLASSIC LOGO COLOR BEANIE navy", "49,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_06, "원브릴리언트", "Ivan-OB166-Black", "112,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_07, "시엔느", "Washing Lettering Ball Cap (Navy)", "49,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_08, "마뗑킴", "ACCORDION WALLET IN WHITE", "88,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_09, "마리떼 프랑소와 저버", "CIRCLE LOGO SATIN HAIRBAND ivorye", "29,000원"))
        itemList.add(RecyclerModel(R.drawable.item_lv_10, "리엔느와르","Dot Toggle Pearl Necklace (2color)", "57,000원"))

        val adapter = RecyclerHorizontalAdapter(itemList)
        binding.recyclerview.adapter = adapter
        binding.recyclerview.layoutManager = GridLayoutManager(this, 2)

        adapter.setItemClickListener(object: RecyclerHorizontalAdapter.onItemClickListener{
            override fun onItemClick(position: Int) {
                Toast.makeText(applicationContext, "RecyclerView: ${itemList[position].title}", Toast.LENGTH_SHORT).show()
            }
        })
    }
}
profile
개발 공부 기록 🌱

0개의 댓글