Android Kotlin RecyclerView Header/Footer - 리사이클러뷰(상하단 레이아웃)
Notepad96
·2021. 10. 25. 18:37
1. 결과
2. Layout
2-1. activity_main.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=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerList"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
2-2. list_header.xml (리스트 헤더 레이아웃)
<?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="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Title"
android:textSize="22sp"
android:textStyle="bold"
android:textColor="@color/black"
android:layout_marginLeft="40dp"/>
<LinearLayout
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/black"/>
<TextView
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="Content"
android:textSize="22sp"
android:textStyle="bold"
android:textColor="@color/black"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#333333"/>
</LinearLayout>
# RecyclerView에서 Header로 사용할 Layout
2-3. list_item.xml (리스트 아이템 레이아웃)
<?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="wrap_content"
android:id="@+id/layoutItem"
android:orientation="vertical">
<TextView
android:id="@+id/layoutEmpty"
android:layout_width="match_parent"
android:layout_height="500dp"
android:layout_weight="1"
android:gravity="center"
android:visibility="gone"
android:text="리스트가 비었습니다."
android:textSize="22sp"
android:textColor="@color/black"/>
<LinearLayout
android:id="@+id/layoutNotEmpty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:layout_width="40dp"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="0dp"/>
<TextView
android:id="@+id/textListTitle"
android:layout_width="100dp"
android:layout_height="match_parent"
android:text="Test Title 1"
android:textSize="18sp"
android:textColor="@color/black"
android:gravity="center_vertical"/>
<LinearLayout
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/black"/>
<TextView
android:id="@+id/textListContent"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginLeft="5dp"
android:gravity="center_vertical"
android:text="Test Content 1"
android:textSize="16sp"
android:textColor="@color/black"/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/black"
/>
</LinearLayout>
# RecyclerView에서 Item(항목)으로 사용할 Layout
2-4. list_footer.xml (리스트 푸터 레이아웃)
<?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="wrap_content"
android:gravity="center"
android:background="#ededed"
android:id="@+id/layoutListFooter"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_add_circle_24"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="5dp"
android:gravity="center_vertical"
android:text="Item Add"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/black"/>
</LinearLayout>
# RecyclerView에서 Footer로 사용할 Layout
3. ListAdapter.kt (리스트 어뎁터)
package com.example.recyclerview03
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager.widget.ViewPager
import kotlinx.android.synthetic.main.list_footer.view.*
import kotlinx.android.synthetic.main.list_item.view.*
class ListAdapter(var list: ArrayList<String>): RecyclerView.Adapter<ListAdapter.ListViewHolder>() {
val HEADER = 1
val ITEM = 2
val FOOTER = 3
class ListViewHolder(val layout: View): RecyclerView.ViewHolder(layout)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
var view =
when(viewType) {
HEADER ->
LayoutInflater.from(parent.context).inflate(R.layout.list_header, parent, false)
FOOTER ->
LayoutInflater.from(parent.context).inflate(R.layout.list_footer, parent, false)
else ->
LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
}
return ListViewHolder(view)
}
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
if(position == 0) {
// HEADER
} else if(position == list.size + 1) {
// FOOTER
holder.layout.layoutListFooter.setOnClickListener {
list.add("")
this.notifyDataSetChanged()
}
} else {
// ITEM
holder.layout.textListTitle.text = "Title $position"
holder.layout.textListContent.text = "Contents $position"
}
}
override fun getItemCount(): Int {
return list.size + 2
}
override fun getItemViewType(position: Int): Int {
return if(position == 0) {
HEADER
} else if(position == list.size + 1) {
FOOTER
} else {
ITEM
}
}
}
# getItemViewType 함수를 override 한다.
그리고 position 값이 0 즉 맨 앞일 경우 HEADER의 값을 보내어 onCreateViewHolder에서 Header용으로 구성한 레이아웃을 불러오도록 한다.
이후 onBindViewHolder에서도 position 값에 따라서 값처리를 구분해주면 된다.
같은 방식으로 Footer 또한 구성 및 처리가 가능하다.
※ onBindViewHolder에서도 반드시 구분을 해주어야 한다. 각 layout마다 포함된 View Object가 다르기 때문에 구분을 해주지 않는다면, Header 레이아웃을 불러왔지만 Footer View Object의 접근하여 동작을 지정하고자 하는 것처럼 에러 발생의 원인이 될 수 있다.
# Item(항목)이 하나도 없을 경우에도 Header와 Footer를 보여주기 위해서 getItemCount에서 Item의 개수의 +2를 해주어야 한다.
따라서 Item이 하나도 없을 경우에도 Size는 0 + 2 = 2로서 Header/Footer가 표시된다.
※ 리사이클러뷰를 여러 곳에서 사용하거나 Header/Footer를 고정된 형태로 구성하고자 하면 Recyclerview를 선언한 Layout에서 위아래의 View Object를 구성하는 것도 하나의 방법이다.
(위 예시에서는 activity_main.xml 속 recyclerview 위 아래의 view 구성)
4. MainActivity.kt
package com.example.recyclerview03
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var list = arrayListOf<String>()
var listManager = LinearLayoutManager(this)
var listAdapter = ListAdapter(list)
var recyclerView = recyclerList.apply {
setHasFixedSize(true)
layoutManager = listManager
adapter = listAdapter
}
}
}
# MainActivity 코드는 이전 간단한 RecyclerView를 선언했을 때와 동일한 구성
5. 전체 코드
'Android' 카테고리의 다른 글
Android Kotlin Intent putExtra, getExtra - 값 전달, 값 받기 (0) | 2021.10.31 |
---|---|
Android Kotlin Double Click Close - 두 번 클릭하여 종료 (0) | 2021.10.27 |
Android Kotlin RecyclerView Grid - 리사이클러뷰(격자형, 표 형식) (0) | 2021.10.25 |
Android Kotlin RecyclerView - 리사이클러뷰(가로, 세로) (1) | 2021.10.24 |
Android Kotlin BottomSheetBehavior - 하단 시트 띄우기 (0) | 2021.10.10 |