개인 개발을 하다 RecyclerView 내부에 CheckBox를 추가할 일이 있었는데,
체크박스에 체크를 하고 스크롤을 내렸다가 다시 올리면 체크해놓은 아이템의 체크값이 초기화 되는 문제점이 있었다.
이를 어떻게 해결할까 구글링 해본결과 역시 해결책을 찾을 수 있었다.
내 소스는 xml과 Java 파일의 내용이 길어 짧은 스택오브플로우의 구글링한 코드를 가져왔다.
xml layout 파일이다. RecyclerView 내부에 포함될 CardView 안에 TextView, CheckBox이 포함되어 있음을 볼 수 있다.
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/cvItems"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_margin="2dp"
card_view:cardElevation="0dp"
card_view:contentPadding="0dp"
card_view:cardBackgroundColor="#FFFFFF"
>
<LinearLayout
android:orientation="horizontal"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<TextView
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="0.8"
android:id="@+id/tvContent"
android:textSize="15dp"
android:paddingLeft="5dp"
android:paddingRight="5dp" />
<CheckBox
android:id="@+id/cbSelect"
android:layout_width="0dip"
android:layout_weight="0.2"
android:layout_height="match_parent"
android:button="@drawable/cb_checked"
android:gravity="center_horizontal"
android:textAlignment="center"
android:layout_gravity="center_horizontal" />
</LinearLayout>
</android.support.v7.widget.CardView>
해당 Java 파일이다. RecyclerView를 사용할때 보통 다음과 같이 구성할 것이다.
public class AdapterTrashIncome extends RecyclerView.Adapter<AdapterTrashIncome.ViewHolder> {
private ArrayList<ObjectIncome> myItems = new ArrayList<>();
public AdapterTrashIncome(ArrayList<ObjectIncome> getItems, Context context){
mContext = context;
myItems = getItems;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView tvContent;
public CheckBox cbSelect;
public ViewHolder(View v) {
super(v);
tvContent = (TextView) v.findViewById(R.id.tvContent);
cbSelect = (CheckBox) v.findViewById(R.id.cbSelect);
}
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
final ObjectIncome objIncome = myItems.get(position);
String content = "<b>lalalla</b>";
holder.tvContent.setText(Html.fromHtml(content));
//if true, your checkbox will be selected, else unselected
holder.cbSelect.setChecked(objIncome.isSelected());
holder.cbSelect.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//set your object's last status
objIncome.setSelected(isChecked);
}
});
}
}
나의 경우에 위의 소스코드와 비슷하게 작성 하였는데
//if true, your checkbox will be selected, else unselected
holder.cbSelect.setChecked(objIncome.isSelected());
소스를 보면 체크값들을 읽어 RecyclerView 안에 CheckBox 값을 초기화 해준 뒤, 앞으로 사용자가 체크할 값에 대해서
Check Event를 달아서 setSelected를 해줌으로써 CheckBox에 체크를 할 수 있게 하였다.
그런데 위의 소스대로 해보면 RecyclerView를 아래로 스크롤 했다 다시 위로 올렸을시, 체크값이 초기화가 되는 문제가 발생한다.
해결책은 다음과 같다.
//in some cases, it will prevent unwanted situations
holder.cbSelect.setOnCheckedChangeListener(null);
//if true, your checkbox will be selected, else unselected
holder.cbSelect.setChecked(objIncome.isSelected());
holder.cbSelect.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//set your object's last status
objIncome.setSelected(isChecked);
}
});
위의 소스와 같이 아래의 해당 코드를 넣어 setOnCheckedChangeListener에 null 값으로 우선 초기화를 해준 뒤
holder.cbSelect.setOnCheckedChangeListener(null);
기존 의 setChecked와 리스너를 사용하게되면 정상 작동함을 알 수 있다.
'개발 공부 기록하기 > - Android' 카테고리의 다른 글
안드로이드 WebView에서 GPS를 사용하는 방법 (2) | 2017.09.17 |
---|---|
[Android] adb 사용하여 USB선연결 없이 apk 설치하기 (0) | 2017.06.26 |
View 이벤트 번짐효과 (ripple effect) 주기 (0) | 2017.05.11 |
Fragment 내에서 Snackbar 사용하기 (0) | 2017.05.01 |
Android 네트워크 연결 상태 체크 하기 (0) | 2017.04.30 |