안녕하세요 이번에는 정말 핵심적인 View인 RecyclerView의 사용법에 대해 알아보겠습니다.
RecyclerView는 뜻대로 재사용 뷰입니다. 기존의 리스트뷰 사용 시 리소스를 많이 잡아먹는 문제점을 해결하기 위해 스크롤을 할 때마다 기존의 View들을 재사용하여 적은 리소스를 사용하도록 만들어진 뷰입니다.
RecyclerView의 속성
android:orientation="vertical" <!-- 리사이클러뷰의 방향 (vertical, horizontal) -->
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" <!-- RecyclerView의 Layout형태 (LinearLayout, GridLayout, StaggeredGridLayoutManager) -->
android:overScrollMode="never" <!-- 스크롤 시 animation (never, always, ifContentScrolls)
먼저 orientation은 리사이클러뷰의 방향(가로, 세로)을 설정합니다.
layoutManager는 리사이클러뷰에서 자식 뷰들의 배치 방식을 지정합니다. LinearLayout은 순차적으로 배치, GridLayout은 격자 형태로 배치
overScrollMode는 끝까지 스크롤했을 때 보여지는 애니메이션을 설정하는 것으로 never는 보이지 않게, always는 항상 보이게, ifContentScrolls는 스크롤이 가능할 때만 보이게 합니다. overScrollMode는 스크롤이 가능한 모든 View에서 사용 가능한 속성입니다.
RecyclerViewAdapter의 속성
adapter.notifyDataSetChanged() //모든 목록 새로고침
adapter.notifyItemInserted(position: Int) //아이템이 추가됨
adapter.notifyItemRemoved(position: Int) //아이템이 삭제됨
adapter.notifyItemChanged(position: Int) //아이템이 변경됨
adapter.notifyItemMoved(fromPosition: Int, toPosition: Int) //아이템이 이동함
adapter.notifyItemRangeChanged(positionStart: Int, itemCount: Int) //여러 아이템이 변경됨
adapter.notifyItemRangeInserted(positionStart: Int, itemCount: Int) //여러 아이템이 추가됨
adapter.notifyItemRangeRemoved(positionStart: Int, itemCount: Int) //여러 아이템이 삭제됨
RecyclerView는 Adapter라는 것이 존재합니다. 이 Adapter에서 RecyclerView의 View들을 설정하고 표현해 줍니다.
notifyItemInserted는 배열에 아이템을 추가하고 추가했다고 Adapter에 알려주어 추가된 아이템을 보여줍니다.
notifyItemRemoved는 배열에 아이템을 삭제한 후 Adapter에 알려주여 삭제하여 보여줍니다.
notifyItemChanged는 배열에 아이템을 수정한 후 Adapter에 알려주어 수정된 내용을 보여줍니다.
notifyItemMoved는 아이템의 순서를 변경한 후 Adapter에 알려주어 변경된 순서를 보여줍니다.
RecyclerView 예제
간단하게 EditText에 내용을 입력하고 입력한 내용을 추가/삭제하여 RecyclerView에 표현하는 예제를 만들어 보도록 하겠습니다.
먼저 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:padding="10dp">
<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text=""
app:layout_constraintEnd_toStartOf="@id/btnAdd"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ADD"
app:layout_constraintEnd_toStartOf="@id/btnRemove"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnRemove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="REMOVE"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.StaggeredGridLayoutManager"
app:layout_constraintTop_toBottomOf="@id/btnAdd" />
</androidx.constraintlayout.widget.ConstraintLayout>
다음은 RecyclerView에 사용할 자식 뷰를 생성해 주어야 합니다. 저는 파일이름을 view_recyclerview_list_item.xml로 생성하여 만들겠습니다.
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="10dp">
</TextView>
간단하게 TextView만 생성하겠습니다.
이제 MainActivity.kt를 수정해 보도록 하겠습니다.
class MainActivity : AppCompatActivity(), View.OnClickListener {
private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
// RecyclerView에 사용될 데이터 ArrayList
private val arrayData = ArrayList<String>()
// RecyclerView의 Adapter
private var recyclerAdapter: RecyclerViewAdapter? = null
override fun onClick(v: View?) {
when(v?.id) {
// ADD버튼을 눌렀을 때 동작
binding.btnAdd.id -> {
if (binding.editText.text.isNullOrEmpty()) {
// EditText가 비어있을 경우 Toast메시지 띄움
Toast.makeText(this, "데이터 입력한 후 추가", Toast.LENGTH_SHORT).show()
} else {
// EditText가 비어있지 않을 경우 ArrayList에 데이터를 추가하고
// adapter에 notifyItemInserted
arrayData.add(binding.editText.text.toString())
recyclerAdapter?.notifyItemInserted(arrayData.size - 1)
}
}
// REMOVE버튼을 눌렀을 때 동작
binding.btnRemove.id -> {
// EditText의 내용이 ArrayList에 포함되어있는지와 Index체크
val removePosition = arrayData.indexOfFirst { it == binding.editText.text.toString() }
if (removePosition != -1) {
// 포함되어 있을 경우 ArrayList에서 해당 내용 삭제 후
// adapter에 notifyRemoved
arrayData.removeAt(removePosition)
recyclerAdapter?.notifyItemRemoved(removePosition)
} else {
// 포함되어 있지 않을 경우 Toast 메시지
Toast.makeText(this, "일치하는 데이터 없음", Toast.LENGTH_SHORT).show()
}
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
// recyclerAdapter 생성 후 recyclerView의 adapter 지정
recyclerAdapter = RecyclerViewAdapter(arrayData)
binding.recyclerView.adapter = recyclerAdapter
// Button들의 ClickListener 생성
binding.btnAdd.setOnClickListener(this)
binding.btnRemove.setOnClickListener(this)
}
}
이제 RecyclerView의 Adapter를 생성 해보겠습니다.
class RecyclerViewAdapter(private val data: ArrayList<String>): RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {
// Adapter의 ViewHolder 생성
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(ViewRecyclerviewListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
override fun onBindViewHolder(holder: RecyclerViewAdapter.ViewHolder, position: Int) {
//생성된 ViewHolder의 bind() 메서드 실행 (이 부분은 RecyclerView의 각 포지션 마다 실행됨)
holder.bind()
}
// RecyclerView 아이템 크기
override fun getItemCount(): Int = data.size
inner class ViewHolder(private val binding: ViewRecyclerviewListItemBinding): RecyclerView.ViewHolder(binding.root) {
fun bind() {
// 해당되는 포지션의 Item으로 TextView의 Text를 수정
binding.textView.text = data[adapterPosition]
}
}
}
이렇게 만들어 주고 나서 실행을 하면 아래처럼 작동되는 것을 확인하실 수 있습니다.
위 코드는 아래의 제 Github에서 확인할 수 있습니다!
GitHub - won-droid/practice: 뷰 사용 예제
뷰 사용 예제. Contribute to won-droid/practice development by creating an account on GitHub.
github.com
이번에는 RecyclerView에 대해 알아보았습니다. 이해가 되지 않거나 다른 궁금한 점, 잘못된 점이 있다면 댓글을 남겨주세요!
'Android > Design' 카테고리의 다른 글
[Android] 안드로이드 레이아웃 - FrameLayout(프레임 레이아웃) 사용 방법 (0) | 2022.06.29 |
---|---|
[Android] 안드로이드 레이아웃 - GridLayout(그리드 레이아웃) 사용 방법 (0) | 2022.06.17 |
[Android] 안드로이드 레이아웃 - TableLayout(테이블 레이아웃) 사용 방법 (0) | 2022.06.17 |
[Android] 안드로이드 레이아웃 - ConstraintLayout(컨스트레인트 레이아웃) 사용 방법 (0) | 2022.06.15 |
[Android] 안드로이드 레이아웃 - RelativeLayout(렐러티브 레이아웃) 사용 방법 (0) | 2022.06.13 |