[안드로이드] RecyclerView 업데이트 및 갱신 방법
RecyclerView 업데이트 및 갱신 방법
RecyclerView의 아이템 내용이 변경되거나 아이템이 추가/이동/삭제 되었을 경우 RecyclerView에 반영하는 방법에 대해서 알아보고자 합니다.
RecyclerView를 업데이트 및 갱신 하기 위해서는 내용 변경후 어댑터에 알려주면 됩니다.
이 때 사용되는 메소드는 아이템 내용이 변경되었을때 사용하는것과 구조가 변경 되었을때 사용하는것으로 구분됩니다.
- 아이템변경 : 아이템 내용이 변경되고 위치 변경은 일어나지 않은 경우
- 구조변경 : DataSet안에서 아이템이 추가, 삭제, 이동되었을 경우
RecyclerView의 데이터를 변경한 후 이를 반영하도록 어댑터에 알려주는 메소드는 아래와 같습니다.
1. 리스트의 변경 알림 메소드 종류 (요약)
[전체적으로 변경되었을 경우]
1) notifyDataSetChanged()
[아이템 내용 변경시]
2) notifyItemChanged(int)
3) notifyItemChanged(int, Object)
4) notifyItemRangeChanged(int, int)
5) notifyItemRangeChanged(int, int, Object)
[아이템 추가시]
6) notifyItemInserted(int)
7) notifyItemRangeInserted(int, int)
[아이템 이동시]
8) notifyItemMoved(int, int)
[아이템 삭제시]
9) notifyItemRemoved(int)
10) notifyItemRangeRemoved(int, int)
2. 리스트의 변경 알림 메소드 설명 (상세)
1) notifyDataSetChanged()
public final void notifyDataSetChanged()
: 사용하기는 편하나 기본적으로 변경사항에 대한 내용을 지정하지 않으므로 모든 아이템과 구조가 유효하지 않다고 가정하고 업데이트를 하므로 성능 측면에서의 효율성은 떨어진다.
2) notifyItemChanged(int)
public final void notifyItemChanged(int position)
: 아이템 한개의 내용이 변경되었을 경우 사용한다.
- position : 변경된 아이템의 위치
3) notifyItemChanged(int, Object)
public final void notifyItemChanged(int position, Object payload)
: 2번과 동일하나 payload를 옵션으로 사용할 수 있음
- position : 변경된 아이템의 위치
- payload : 옵션이며, 어댑터의 onBindViewholder()가 호출될때 넘겨받을 수 있는 객체이다. 따라서 특정 position의 내용을 payload값으로 구분하여 업데이트 할때 사용된다.
4) notifyItemRangeChanged(int, int)
public final void notifyItemRangeChanged(int positionStart, int itemCount)
: 연속된 여러개의 아이템 내용이 변경되었을 경우 사용한다.
- positionStart : 변경된 아이템의 시작 위치
- itemCount : 변경된 아이템의 갯수
5) notifyItemRangeChanged(int, int, Object)
public final void notifyItemRangeChanged(int positionStart, int itemCount, Object payload)
: 4)번과 동일하나, payload를 옵션으로 사용할 수 있음
- positionStart : 변경된 아이템의 시작 위치
- itemCount : 변경된 아이템의 갯수
- payload : 옵션이며, 어댑터의 onBindViewholder()가 호출될때 넘겨받을 수 있는 객체이다. 따라서 특정 position의 내용을 payload값으로 구분하여 업데이트 할때 사용된다.
6) notifyItemInserted(int)
public final void notifyItemInserted(int position)
: 아이템 한개를 새로 추가할 경우 사용한다.
- position : 추가된 아이템의 위치
7) notifyItemRangeInserted(int, int)
public final void notifyItemRangeInserted(int positionStart, int itemCount)
: 연속된 아이템을 추가할 경우 사용한다.
- positionStart : 추가된 아이템의 시작 위치
- itemCount : 추가된 아이템의 갯수
8) notifyItemMoved(int, int)
public final void notifyItemMoved(int fromPosition, int toPosition)
: 한개의 아이템 위치를 이동할 경우 사용한다.
- fromPosition : 기존 아이템 위치
- toPosition : 변경될 아이템 위치
9) notifyItemRemoved(int)
public final void notifyItemRemoved(int position)
: 한개의 아이템을 삭제할 경우 사용한다.
- position : 삭제할 아이템의 위치
10) notifyItemRangeRemoved(int, int)
public final void notifyItemRangeRemoved(int positionStart, int itemCount)
: 연속된 여러개의 아이템을 삭제할 경우 사용한다.
- positionStart : 삭제할 아이템의 시작 위치
- itemCount : 삭제할 아이템의 갯수
3. 리스트의 변경 알림 메소드 사용법
아이템의 내용 변경후 어댑터에 해당 메소드를 통해 알려주면 됩니다.
ex) customAdapter.notifyDataSetChanged();
4. 리스트 데이터 추가/삭제 기능 예제
앞서 작성한 기본적인 RecyclerView 사용법에서 데이터 추가/삭제 기능을 추가한 코드입니다.
[기본적인 RecyclerView 사용법은 아래글을 참고하세요]
2021.12.29 - [IT 개발/Android] - [안드로이드] RecyclerView 사용법 (리사이클러뷰)
[MainActivity.java]
public class MainActivity extends AppCompatActivity {
int newDataNumber = 100;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//----- 테스트를 위한 더미 데이터 생성 --------------------
ArrayList<String> testDataSet = new ArrayList<>();
for (int i = 0; i<20; i++) {
testDataSet.add("TEST DATA" + i);
}
//--------------------------------------------------------
RecyclerView recyclerView = findViewById(R.id.recyclerView);
//--- LayoutManager는 아래 3가지중 하나를 선택하여 사용 ----
// 1) LinearLayoutManager()
// 2) GridLayoutManager()
// 3) StaggeredGridLayoutManager()
//---------------------------------------------------------
LinearLayoutManager linearLayoutManager = new LinearLayoutManager((Context) this);
recyclerView.setLayoutManager(linearLayoutManager); // LayoutManager 설정
CustomAdapter customAdapter = new CustomAdapter(testDataSet);
recyclerView.setAdapter(customAdapter); // 어댑터 설정
//===== [데이터 추가/삭제 기능을 위해 추가된 코드] ===========
Button buttonAddItem = findViewById(R.id.buttonAddItem);
Button buttonDeleteItem = findViewById(R.id.buttonDeleteItem);
buttonAddItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
testDataSet.add("NEW DATA " + newDataNumber++);
customAdapter.notifyItemInserted(testDataSet.size());
}
});
buttonDeleteItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
testDataSet.remove(testDataSet.size()-1);
customAdapter.notifyDataSetChanged(); // 만능, 되도록 사용x
}
});
//==========================================================
}
}
[activity_main.xml]
- 데이터 추가/삭제용 Button 두개 추가
<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="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RecyclerView 테스트"
android:textSize="32dp"
android:textColor="#FFFFFFFF"
android:padding="8dp"
android:background="#FF3F3F3F"
android:gravity="center"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/buttonAddItem"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="아이템 추가"
android:textSize="24dp"
android:textColor="#FFFFFFFF"
android:layout_margin="8dp"
android:padding="8dp"
android:backgroundTint="#FFFF0000"
android:layout_gravity="center"/>
<Button
android:id="@+id/buttonDeleteItem"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="아이템 삭제"
android:textSize="24dp"
android:textColor="#FFFFFFFF"
android:layout_margin="8dp"
android:padding="8dp"
android:backgroundTint="#FF0000FF"
android:layout_gravity="center"/>
</LinearLayout>
</LinearLayout>
참고자료
https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.Adapter