관리 메뉴

나만을 위한 블로그

[Android] 리사이클러뷰 아이템 안의 체크박스의 체크 상태를 유지시키는 법 본문

Android

[Android] 리사이클러뷰 아이템 안의 체크박스의 체크 상태를 유지시키는 법

참깨빵위에참깨빵_ 2020. 12. 24. 10:47
728x90
반응형

리사이클러뷰를 쓰다 보면 아이템 안에 체크박스를 추가해야 할 때가 생길 수 있다.

그러나 막상 만든 다음 체크하고 스크롤을 내렸더니 체크하지 않았던 항목이 체크되어 있는 경우가 있다. 그리고 이 상태에서 다시 스크롤을 올리면 체크했던 항목이 체크해제되어 있는 경우도 있다. 뭐야 내 체크박스 돌려줘요

이번 포스팅에선 리사이클러뷰 아이템 안의 체크박스에 체크한 다음 스크롤을 이동해도 체크상태가 유지될 수 있도록 하는 방법을 기록하려고 한다.

 

먼저 모델 클래스를 만들 때 아래와 같이 만든다.

 

public class Item
{
    boolean isSelected;

    public boolean getSelected()
    {
        return isSelected;
    }

    public void setSelected(boolean selected)
    {
        isSelected = selected;
    }
}

 

다른 변수는 제외하고 체크박스에 사용할 boolean 변수와 그것의 게터세터만 썼다.

다음은 어댑터 부분이다. 이 부분이 중요한데, 액티비티에서 체크박스의 상태를 관리하는 것이 아니라 어댑터에서 관리해야 한다.

주목해야 할 부분은 onBindViewHolder()다.

 

@Override
    public void onBindViewHolder(@NonNull MyAdapter.MyViewHolder holder, int position)
    {
        // final로 선언해야 체크박스의 체크 상태값(T/F)이 바뀌지 않는다
        final Item item = list.get(position);
        
        // 먼저 체크박스의 리스너를 null로 초기화한다
        holder.checkbox.setOnCheckedChangeListener(null);
        
        // 모델 클래스의 getter로 체크 상태값을 가져온 다음, setter를 통해 이 값을 아이템 안의 체크박스에 set한다
        holder.checkbox.setChecked(item.getSelected());
        
        // 체크박스의 상태값을 알기 위해 리스너 부착
        holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
        {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
            {
                // 여기의 item은 final 키워드를 붙인 모델 클래스의 객체와 동일하다
                item.setSelected(isChecked);
            }
        });
    }

 

onBindViewHolder() 안의 첫 줄에서는 모델 클래스의 객체를 만드는데, 이 때 final 키워드를 붙여서 스크롤 시 체크한 체크박스의 값이 바뀌지 않도록 한다.

2번째로 체크박스의 리스너를 null로 초기화한다. 내 경우에는 저 코드를 쓰지 않으면 아주 가끔 체크 상태가 변동되는 현상이 있어서 쓰게 됐다.

3번째로 아이템 안의 체크박스에 setter로 체크 상태값을 set한다. 여기서 체크 상태값은 getter로 가져온 T/F 값이다. 체크를 했다면 스크롤을 해도 체크된 상태로 남아있도록 하는 것이다.

 

여기서 마무리해도 될 것 같지만 아니다. null로 초기화한 체크박스 리스너를 알맞은 리스너로 바꿔준 다음, 콜백에서도 모델 클래스의 setter를 통해 값을 한번 더 set해줘야 에러가 발생할 여지가 사라진다.

체크박스기 때문에 CompoundButton.OnCheckedChangeListener()를 호출해줘야 한다. 옛날 글을 보면 그냥 OnCheckedChangeListener()만 있는 걸 볼 수 있는데, 옛날이라 그런 거다.

 

이렇게 한 다음 앱을 빌드해 테스트해 보면 아이템 안의 체크박스 상태가 스크롤해도 유지되는 걸 볼 수 있다.

반응형
Comments