일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 안드로이드 갤러리 접근
- Android ViewPager2
- Android 12 대응
- Android Jetpack
- Android Interceptor
- WebView
- Android
- Android WebView
- scope function
- android recyclerview
- Android DataBinding
- Kotlin FCM
- Android ProgressBar
- Java
- 안드로이드
- 습관만들기
- Kotlin
- 알고리즘 자바
- 66챌린지
- OkHttp Interceptor
- Android 12
- DataBinding
- 안드로이드 fcm
- 안드로이드 카카오 로그인
- 카카오 알고리즘
- 영어독립365
- 프로그래머스 알고리즘
- Android Navigation
- MVP Architecture
- 영어공부
Archives
- Today
- Total
Developer Geek
[Android] RecyclerView 아이템 여백 설정 본문
반응형
GridSpaceItemDecoration: RecyclerView 아이템 여백 설정
개요
RecyclerView를 통해서 Grid 형태의 아이템들을 그려야할 때, 단순히 아이템의 레이아웃만으로 일정한 여백을 추가하기는 까다롭다.
예를 들어 SpanCount = 2
이고 각 아이템에 20dp
에 해당하는 Padding 값을 할당했다고 한다면, 다음과 같이 아이템 간의 사이는 40dp
가 되고 상하좌우의 끝의 여백만이 20dp
가 될 것이다.
물론 RecyclerView의 Padding 값을 20dp
로 추가로 설정한다면 모든 간격이 40dp
로 일정하게 만들수는 있다.
하지만 아이템의 여백 설정을 위해 2가지 아이템(2가지 레이아웃 파일)에서 관리하는건 유지보수 하는 입장에서 좋지 않다.
그래서 ItemDecoration을 이용해서 Grid 형태의 아이템들에 같은 여백을 줄 수 있는 GradSpaceItemDecoration 을 만들어 보겠다.
실행 화면
상하좌우 끝의 여백을 포함해 모두 같은 여백을 갖음
상하좌우 끝의 여백을 포함하지 않고 아이템 간의 여백만을 갖음
Code
GridSpaceItemDecoration.kt - 상하좌우 끝의 여백을 포함해 모두 같은 여백을
아이디어
getItemOffSets()
함수를 이용해서, 첫번째 행(row-1)에 있는 아이템들에만 상단에 여백을 주고, 모든 아이템에는 하단에 여백을 준다.
그리고 같은 개념으로 첫번째 열(column-1)에 있는 아이템들만 좌측에 여백을 주고, 모든 아이템에는 우측에 여백을 준다.
class GridSpaceItemDecoration(private val spanCount: Int, private val space: Int): RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val position = parent.getChildAdapterPosition(view)
val column = position % spanCount + 1 // 1부터 시작
/** 첫번째 행(row-1)에 있는 아이템인 경우 상단에 [space] 만큼의 여백을 추가한다 */
if (position < spanCount){
outRect.top = space
}
/** 마지막 열(column-N)에 있는 아이템인 경우 우측에 [space] 만큼의 여백을 추가한다 */
if (column == spanCount){
outRect.right = space
}
/** 모든 아이템의 좌측과 하단에 [space] 만큼의 여백을 추가한다. */
outRect.left = space
outRect.bottom = space
}
}
GridSpaceItemDecoration.kt - 상하좌우 끝의 여백을 포함하지 않고 아이템 간의 여백만을 갖음
class GridSpaceItemDecoration(private val spanCount: Int, private val space: Int): RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val position = parent.getChildAdapterPosition(view)
val column = position % spanCount + 1 // 1부터 시작
/** 첫번째 행(row-1) 이후부터 있는 아이템에만 상단에 [space] 만큼의 여백을 추가한다. 즉, 첫번째 행에 있는 아이템에는 상단에 여백을 주지 않는다.*/
if (position >= spanCount){
outRect.top = space
}
/** 첫번째 열이 아닌(None Column-1) 아이템들만 좌측에 [space] 만큼의 여백을 추가한다. 즉, 첫번째 열에 있는 아이템에는 좌측에 여백을 주지 않는다. */
if (column != 1){
outRect.left = space
}
}
}
build.gradle(Module): ViewBinding 사용
android {
...
buildFeatures{
viewBinding true
}
}
item_layout.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white">
<ImageView
android:id="@+id/imageView"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_marginVertical="5dp"
android:layout_marginStart="8dp"
android:src="@drawable/ic_launcher_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="TITLE"
app:layout_constraintBottom_toBottomOf="@id/imageView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView"
app:layout_constraintTop_toTopOf="@id/imageView" />
</androidx.constraintlayout.widget.ConstraintLayout>
ItemAdapter.kt
class ItemAdapter: RecyclerView.Adapter<ItemAdapter.ViewHolder>() {
private var itemList = arrayListOf<String>()
inner class ViewHolder(private val binding: ItemLayoutBinding): RecyclerView.ViewHolder(binding.root){
fun bind(title: String){
binding.run{
tvTitle.text = title
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
return ViewHolder(ItemLayoutBinding.inflate(inflater, parent, false))
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(itemList[position])
}
override fun getItemCount(): Int = itemList.size
fun submitList(arrayList: ArrayList<String>){
itemList = arrayList
notifyDataSetChanged()
}
}
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout 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:background="#ECECEC"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:spanCount="2"
tools:listitem="@layout/item_layout" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initView()
}
private fun initView() {
val recyclerViewAdapter = ItemAdapter().apply {
val itemList = arrayListOf(
"타이틀 - 1",
"타이틀 - 2",
"타이틀 - 3",
"타이틀 - 4",
"타이틀 - 5",
"타이틀 - 6",
"타이틀 - 7"
)
this.submitList(itemList)
}
binding.recyclerView.adapter = recyclerViewAdapter
binding.recyclerView.run {
adapter = recyclerViewAdapter
val spanCount = 2
val space = 20
addItemDecoration(GridSpaceItemDecoration(spanCount, space))
}
}
}
질문과 잘못된 점에 대해 말씀해주시는 건 언제나 환영입니다.
zero5.two4@gmail.com
반응형
'안드로이드 > View' 카테고리의 다른 글
[Android] WebView Bridge Basic Sample (1) | 2022.09.30 |
---|---|
[Android] Spannable Click Event Example (0) | 2022.09.25 |
[Android] RecyclerView Multi-ViewHolder Basic Sample: 채팅 화면 (0) | 2022.08.30 |
[Android] ViewPager2 Basic Sample in Kotlin (0) | 2022.08.10 |
[Android] ViewPager Basic Sample in Kotlin (0) | 2022.08.08 |
Comments