반응형

 

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 사용법 (리사이클러뷰)

 

[안드로이드] RecyclerView 사용법 (리사이클러뷰)

RecyclerView 사용법 (리사이클러뷰) RecyclerView는 대량의 데이터를 효율적으로 화면에 나타내기 위해서, 각 아이템을 목록형태로 화면에 나타내는데 사용됩니다. ListView와 유사하나 아래와 같은 성

kadosholy.tistory.com

 

 

[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

 

RecyclerView.Adapter  |  Android Developers

RecyclerView.Adapter public static abstract class RecyclerView.Adapter extends Object Base class for an Adapter Adapters provide a binding from an app-specific data set to views that are displayed within a RecyclerView. Summary Nested classes enum Recycler

developer.android.com

 

반응형

+ Recent posts