RecyclerView의 CheckBox는 다른 항목을 계속 확인합니다.
RecyclerView 내의 내 항목에 대한 XML은 다음과 같습니다.
<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>
다음은 각 항목에 대해 위의 레이아웃을 확장하는 RecyclerView 어댑터입니다.
public class AdapterTrashIncome extends RecyclerView.Adapter<AdapterTrashIncome.ViewHolder> {
private ArrayList<ObjectIncome> myItems = new ArrayList<>();
public AdapterTrashIncome(ArrayList<ObjectIncome> getItems, Context context){
try {
mContext = context;
myItems = getItems;
}catch (Exception e){
Log.e(FILE_NAME, "51: " + e.toString());
e.printStackTrace();
}
}
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));
}
}
문제는 RecyclerView 안에 10 개의 항목이 있다고 가정 해 보겠습니다. 항목 1,2,3의 확인란을 선택한 다음 RecyclerView를 아래로 스크롤하면 갑자기 다른 항목 (예 : 항목 8,9)이 선택됩니다. 그리고 다시 위로 스크롤하면 항목 1과 3은 확인되지만 항목 2는 확인되지 않습니다. 왜 이런 일이 발생하는지 아십니까?
정상입니다. 확인란을 선택하거나 설정하지 않았습니다. 하나를 선택하고 View holder가 선택한 상태로 유지합니다. ObjectIncome 개체에 부울 변수를 추가하고 항목의 선택 상태를 유지할 수 있습니다.
내 예를 볼 수 있습니다. 다음과 같이 할 수 있습니다.
public class AdapterTrashIncome extends RecyclerView.Adapter<AdapterTrashIncome.ViewHolder> {
private ArrayList<ObjectIncome> myItems = new ArrayList<>();
public AdapterTrashIncome(ArrayList<ObjectIncome> getItems, Context context){
try {
mContext = context;
myItems = getItems;
}catch (Exception e){
Log.e(FILE_NAME, "51: " + e.toString());
e.printStackTrace();
}
}
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));
//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);
}
});
}
}
RECYCLER보기에 제한된 수의 항목이있는 경우에만 이것을 사용하십시오.
모델에서 부울 값을 사용하고 확인란 상태를 유지했지만 제 경우에는 도움이되지 않았습니다. 나를 위해 일한 것은 this.setIsRecyclable (false);
public class ComponentViewHolder extends RecyclerView.ViewHolder {
public MyViewHolder(View itemView) {
super(itemView);
....
this.setIsRecyclable(false);
}
이에 대한 자세한 설명은 https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder.html#isRecyclable () 에서 찾을 수 있습니다.
참고 : 이것은 해결 방법입니다. 이를 올바르게 사용하려면 "setIsRecyclable () 호출은 항상 쌍을 이루어야합니다 (setIsRecyclabe (false) 호출은 항상 나중에 setIsRecyclable (true) 호출과 일치해야 함). 호출 쌍은 중첩 될 수 있습니다. , 상태가 내부적으로 참조 계산되기 때문입니다. " 누군가가 더 많은 코드를 제공 할 수 있다면 코드에서이 작업을 수행하는 방법을 모르겠습니다.
요컨대, 뷰를 재활용하고 다시 사용하기 때문입니다!
어떻게 피할 수 있습니까?
1. onBindViewHolder
체크 박스를 체크 또는 체크 해제해야하는지 체크합니다. if와 else를 모두 입력하는 것을 잊지 마십시오.
if (...)
holder.cbSelect.setChecked(true);
else
holder.cbSelect.setChecked(false);
- 체크 박스에 대한 청취자를 넣으십시오! 체크 된 조각상이 변경 될 때마다
myItems
배열 에서 해당 객체도 업데이트하십시오 ! 따라서 새로운 뷰가 표시 될 때마다 객체의 최신 조각상을 읽습니다.
recyclerview의 두 가지 재정의 방법을 추가하십시오.
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return position;
}
Model 클래스를 사용하여 각 recyclerView 항목의 확인란을 추적 할 수 있습니다. 전체 참조 출처 : RecyclerView Checkbox Android
setTag 및 getTag 는 체크 박스 상태를 추적하는 데 사용됩니다. 자세한 내용은 전체 참조 링크를 확인하십시오. 또한 체크 된 항목을 NEXTACTIVITY 로 보내는 방법을 알려줍니다 .
모형을 만들다
public class Model {
private boolean isSelected;
private String animal;
public String getAnimal() {
return animal;
}
public void setAnimal(String animal) {
this.animal = animal;
}
public boolean getSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
}
integer.xml 생성
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="btnplusview">1</integer>
<integer name="btnpluspos">2</integer>
</resources>
마지막으로 어댑터는 다음과 같습니다.
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
private LayoutInflater inflater;
public static ArrayList<Model> imageModelArrayList;
private Context ctx;
public CustomAdapter(Context ctx, ArrayList<Model> imageModelArrayList) {
inflater = LayoutInflater.from(ctx);
this.imageModelArrayList = imageModelArrayList;
this.ctx = ctx;
}
@Override
public CustomAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.rv_item, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(final CustomAdapter.MyViewHolder holder, int position) {
holder.checkBox.setText("Checkbox " + position);
holder.checkBox.setChecked(imageModelArrayList.get(position).getSelected());
holder.tvAnimal.setText(imageModelArrayList.get(position).getAnimal());
// holder.checkBox.setTag(R.integer.btnplusview, convertView);
holder.checkBox.setTag(position);
holder.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Integer pos = (Integer) holder.checkBox.getTag();
Toast.makeText(ctx, imageModelArrayList.get(pos).getAnimal() + " clicked!", Toast.LENGTH_SHORT).show();
if (imageModelArrayList.get(pos).getSelected()) {
imageModelArrayList.get(pos).setSelected(false);
} else {
imageModelArrayList.get(pos).setSelected(true);
}
}
});
}
@Override
public int getItemCount() {
return imageModelArrayList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
protected CheckBox checkBox;
private TextView tvAnimal;
public MyViewHolder(View itemView) {
super(itemView);
checkBox = (CheckBox) itemView.findViewById(R.id.cb);
tvAnimal = (TextView) itemView.findViewById(R.id.animal);
}
}
}
위에서 언급했듯이 개체의 확인 된 상태는 개체 속성에 포함되어야합니다. 어떤 경우에는 개체 자체를 클릭하여 개체 선택 상태를 변경하고 CheckBox가 실제 상태 (선택 또는 선택 취소)에 대해 알려주도록해야 할 수도 있습니다. 그런 다음 확인란은 (기본적으로 / 대부분의 경우) 목록에있는 요소의 위치 인 지정된 어댑터의 실제 위치에있는 개체의 상태를 사용합니다.
아래 스 니펫을 확인하면 유용 할 수 있습니다.
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import java.io.File;
import java.io.IOException;
import java.util.List;
public class TakePicImageAdapter extends RecyclerView.Adapter<TakePicImageAdapter.ViewHolder>{
private Context context;
private List<Image> imageList;
public TakePicImageAdapter(Context context, List<Image> imageList) {
this.context = context;
this.imageList = imageList;
}
@Override
public TakePicImageAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(context).inflate(R.layout.image_item,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final TakePicImageAdapter.ViewHolder holder, final int position) {
File file=new File(imageList.get(position).getPath());
try {
Bitmap bitmap= MediaStore.Images.Media.getBitmap(context.getContentResolver(), Uri.fromFile(file));
holder.image.setImageBitmap(bitmap
);
} catch (IOException e) {
e.printStackTrace();
}
holder.selectImage.setOnCheckedChangeListener(null);
holder.selectImage.setChecked(imageList.get(position).isSelected());
holder.selectImage.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
holder.selectImage.setChecked(isChecked);
imageList.get(position).setSelected(isChecked);
}
});
holder.image.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (imageList.get(position).isSelected())
{
imageList.get(position).setSelected(false);
holder.selectImage.setChecked(false);
}else
{
imageList.get(position).setSelected(true);
holder.selectImage.setChecked(true);
}
}
});
}
@Override
public int getItemCount() {
return imageList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ImageView image;public CheckBox selectImage;
public ViewHolder(View itemView) {
super(itemView);
image=(ImageView)itemView.findViewById(R.id.image);
selectImage=(CheckBox) itemView.findViewById(R.id.ch);
}
}
}
제 경우에는 이것이 효과가있었습니다.
@Override
public void onViewRecycled(MyViewHolder holder) {
holder.checkbox.setChecked(false); // - this line do the trick
super.onViewRecycled(holder);
}
CheckBox를 사용한 onBindViewHolder (logic) 상호 작용과 확인란을 사용한 사용자 상호 작용을 분리해야합니다. 사용자 상호 작용에는 OnCheckedChangeListener를 사용하고 논리에는 ViewHolder.bind ()를 사용했습니다. 그래서 홀더를 설정하기 전과 홀더가 준비된 후에 확인 된 리스너를 null로 설정해야합니다. 사용자 상호 작용을 위해 확인 된 리스너를 구성해야합니다.
boolean[] checkedStatus = new boolean[numberOfRows];
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
final ViewHolderItem itemHolder = (ViewHolderItem) holder;
//holder.bind should not trigger onCheckedChanged, it should just update UI
itemHolder.checkBox.setOnCheckedChangeListener(null);
itemHolder.bind(position);
itemHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
checkedStatus[holder.getAdapterPosition()] = true;
performCheckedActions(); //your logic here
} else {
checkedStatus[holder.getAdapterPosition()] = false;
performUncheckedActions(); //your logic here
}
}
});
}
public void bind(int position) {
boolean checked = checkedStatus[position];
if (checked) {
checkBox.setChecked(false);
} else {
checkBox.setChecked(true);
}
}
내가 찾은이 솔루션의 문제는 정적 전역 배열을 만들고 필요한 모든 전역 변수 / 객체를 만든 "onBindViewHolder"ADAPER CLASS에서 사용하는 것입니다.
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder> {
private Context context;
public static class PersonViewHolder extends RecyclerView.ViewHolder {
CardView cv;
TextView question,category;
TextView personAge;
ImageView upvote;
Button b1;
public static int k;
private int visibleThreshold = 5;
public static int i=0;
static int check[]; //Static array
PersonViewHolder(View itemView,int i) {
super(itemView);
if(i==PersonViewHolder.k)
{
b1=(Button)itemView.findViewById(R.id.loadmore);
}
else
{
cv = (CardView)itemView.findViewById(R.id.cv);
question = (TextView)itemView.findViewById(R.id.question);
category = (TextView)itemView.findViewById(R.id.text_categ);
personAge = (TextView)itemView.findViewById(R.id.text1);
upvote = (ImageView)itemView.findViewById(R.id.upvote);
}
}
}
여기 (RVADAPTER CLASS의 CONSTRUCTOR에서) 리사이클 러 뷰에 표시 할 항목의 / no 크기와 동일한 배열 크기를 지정했습니다.
List<Person> persons;
RVAdapter(List<Person> persons){
this.persons = persons;
PersonViewHolder.check=new int[persons.size()];
PersonViewHolder.k=persons.size();
}
BindViewHolder, I, 버튼에이 개념을 적용했습니다. 버튼을 클릭하면 버튼의 배경 이미지가 변경됩니다. 내가 사용한 버튼의 객체는 "upvote"로 이름이되는데, "i"는 리사이클 러 뷰에서 각 항목의 위치를 유지하므로 플래그로 작동하고 요소의 상태를 추적하는 배열의 인덱스로 사용했습니다.
@Override
public void onBindViewHolder(final PersonViewHolder personViewHolder, final int i) {
if(i==PersonViewHolder.k) {
personViewHolder.b1.setText("load more");
}
else
{
personViewHolder.question.setText(persons.get(i).name);
personViewHolder.personAge.setText(persons.get(i).age);
if(personViewHolder.check[i]==0)
{personViewHolder.upvote.setBackgroundResource(R.drawable.noupvote);
}
else
{
personViewHolder.upvote.setBackgroundResource(R.drawable.upvote);
}
personViewHolder.upvote.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(personViewHolder.check[i]==0)
{personViewHolder.check[i]=1;
personViewHolder.upvote.setBackgroundResource(R.drawable.upvote);
}
else
{personViewHolder.check[i]=0;
personViewHolder.upvote.setBackgroundResource(R.drawable.noupvote);
}
}
});
// personViewHolder.personPhoto.setImageResource(persons.get(i).photoId);
}
}
나는 같은 문제가 있었다. recyclerView에서 항목의 토글 버튼을 클릭했을 때 10 번째 항목마다 토글 버튼이 표시되었습니다 (예 : 인덱스가 0 인 항목에서 클릭하면 인덱스가 9, 18, 27 인 항목도 클릭 됨). 첫째, onBindViewHolder의 코드는 다음과 같습니다.
if (newsItems.get(position).getBookmark() == 1) {
holder.getToggleButtonBookmark().setChecked(true);
}
하지만 Else 문을 추가했습니다.
if (newsItems.get(position).getBookmark() == 1) {
holder.getToggleButtonBookmark().setChecked(true);
//else statement prevents auto toggling
} else{
holder.getToggleButtonBookmark().setChecked(false);
}
그리고 문제가 해결되었습니다
Kotlin을 사용하여이 문제를 해결 한 유일한 방법 OnCheckedChangeListener
은 변수를 설정하기 전에 지운 다음 설정 한 OnCheckedChangeListener
후에 새 파일을 만드는 checked
것입니다.
내에서 다음을 수행합니다. RecyclerView.ViewHolder
task.setOnCheckedChangeListener(null)
task.isChecked = item.status
task.setOnCheckedChangeListener { _: CompoundButton, checked: Boolean ->
item.status = checked
...
do more stuff
...
}
나는 스위치가있는 RecyclerView 목록에서 동일한 문제가 있었고 @oguzhand 답변을 사용하여 해결했지만이 코드는 checkedChangeListener 내부에 있습니다.
if (buttonView.isPressed()) {
if (isChecked) {
group.setSelected(true);
} else {
group.setSelected(false);
}
}else{
if (isChecked) {
buttonView.setChecked(false);
} else {
buttonView.setChecked(true);
}
}
( '그룹'은 내가 선택 / 선택 취소하려는 엔티티입니다)
좋아요 여기에 많은 답변이 있습니다. 저는 제 코드를 게시하고 제가 한 일을 간단히 설명 할 것입니다 ... 그것은 나 같은 후배들에게 도움이 될 수도 있습니다. : D.
1- 목표 :
우리의 목록을 만들 것 RecyclerView
즉 가지고 CheckBox
와 RadioButton
, 이런 걸 :
public class ModelClass {
private String time;
private boolean checked;
private boolean free;
private boolean paid;
public TherapistScheduleModel(String time, boolean checked, boolean free, boolean paid) {
this.time = time;
this.checked = checked;
this.free = free;
this.paid = paid;
}
public boolean isFree() {
return free;
}
public void setFree(boolean free) {
this.free = free;
}
public boolean isPaid() {
return paid;
}
public void setPaid(boolean paid) {
this.paid = paid;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public boolean getChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked= checked;
}
}
3-My Amazing 어댑터
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private Context context;
private ListAllListeners listAllListeners;
private ArrayList<ModelClass> mDataList;
public MyAdapter(Context context, ArrayList<ModelClass> mDataList,
ListAllListeners listAllListeners) {
this.mDataList = mDataList;
this.listAllListeners = listAllListeners;
this.context = context;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.single_view, parent, false);
return new MyViewHolder(view);
}
@Override
public int getItemCount() {
if (mDataList != null)
return mDataList.size();
else
return 0;
}
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
//important to:
//setOnCheckedChangeListener to 'null'
holder.checkBoxTime.setOnCheckedChangeListener(null);
holder.freeRB.setOnCheckedChangeListener(null);
holder.paidRB.setOnCheckedChangeListener(null);
//Check Box
holder.checkBoxTime.setText(mDataList.get(holder.getAdapterPosition()).getTime());
//here we check if the item is checked or not from the model.
if(mDataList.get(holder.getAdapterPosition()).getChecked())
holder.checkBoxTime.setChecked(true);
else
holder.checkBoxTime.setChecked(false);
holder.checkBoxTime.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
mDataList.get(holder.getAdapterPosition()).setChecked(true);
listAllListeners.onItemCheck(holder.checkBoxTime.getText().toString(), holder.getAdapterPosition());
}
else {
mDataList.get(holder.getAdapterPosition()).setChecked(false);
listAllListeners.onItemUncheck(holder.checkBoxTime.getText().toString(), holder.getAdapterPosition());
}
}
});
//Radio Buttons
if(mDataList.get(holder.getAdapterPosition()).isFree())
holder.freeRB.setChecked(true);
else
holder.freeRB.setChecked(false);
holder.freeRB.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
mDataList.get(holder.getAdapterPosition()).setFree(true);
listAllListeners.onFreeCheck(holder.freeRB.getText().toString(), holder.getAdapterPosition());
} else {
mDataList.get(holder.getAdapterPosition()).setFree(false);
listAllListeners.onFreeUncheck(holder.freeRB.getText().toString(), holder.getAdapterPosition());
}
}
});
//***and so on to paidRB***
}//end onBindViewHolder()
public interface ListAllListeners {
//here is a list of clicked listeners to use them as you want ;).
//you can get a list of checked or unChecked of all
void onItemCheck(String checkBoxName, int position);
void onItemUncheck(String checkBoxName, int position);
void onFreeCheck(String name, int pos);
void onFreeUncheck(String name, int pos);
void onPaidCheck(String name, int pos);
void onPaidUncheck(String name, int pos);
}
class MyViewHolder extends RecyclerView.ViewHolder {
CheckBox checkBoxTime;
RadioButton freeRB, paidRB;
MyViewHolder(View itemView) {
super(itemView);
checkBoxTime = itemView.findViewById(R.id.timeCheckBox);
freeRB = itemView.findViewById(R.id.freeRadioBtn);
paidRB = itemView.findViewById(R.id.paidRadioBtn);
}
}//end class MyViewHolder
}//end class
3- 활동에서 다음과 같이 얻습니다.
myAdapter= new MyAdapter(getActivity().getApplicationContext(), mDataList,
new MyAdapter.ListAllListeners() {
@Override
public void onItemCheck(String checkBoxName, int position) {
Toast.makeText(getActivity(), "" + checkBoxName + " " + position, Toast.LENGTH_SHORT).show();
}
@Override
public void onItemUncheck(String checkBoxName, int position) {
Toast.makeText(getActivity(), "" + checkBoxName + " " + position, Toast.LENGTH_SHORT).show();
}
@Override
public void onFreeCheck(String name, int position) {
Toast.makeText(getActivity(), "" + name + " " + position, Toast.LENGTH_SHORT).show();
}
@Override
public void onFreeUncheck(String name, int position) {
Toast.makeText(getActivity(), "" + name + " " + position, Toast.LENGTH_SHORT).show();
}
@Override
public void onPaidCheck(String name, int position) {
Toast.makeText(getActivity(), "" + name + " " + position, Toast.LENGTH_SHORT).show();
}
@Override
public void onPaidUncheck(String name, int position) {
Toast.makeText(getActivity(), "" + name + " " + position, Toast.LENGTH_SHORT).show();
}
});
Public class TagYourDiseaseAdapter extends RecyclerView.Adapter {private ReCyclerViewItemClickListener mRecyclerViewItemClickListener; 개인 컨텍스트 mContext;
List<Datum> deviceList = Collections.emptyList();
/**
* Initialize the values
*
* @param context : context reference
* @param devices : data
*/
public TagYourDiseaseAdapter(Context context, List<Datum> devices,
ReCyclerViewItemClickListener mreCyclerViewItemClickListener) {
this.mContext = context;
this.deviceList = devices;
this.mRecyclerViewItemClickListener = mreCyclerViewItemClickListener;
}
/**
* @param parent : parent ViewPgroup
* @param viewType : viewType
* @return ViewHolder
* <p>
* Inflate the Views
* Create the each views and Hold for Reuse
*/
@Override
public TagYourDiseaseAdapter.OrderHistoryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_tag_disease, parent, false);
TagYourDiseaseAdapter.OrderHistoryViewHolder myViewHolder = new TagYourDiseaseAdapter.OrderHistoryViewHolder(view);
return myViewHolder;
}
/**
* @param holder :view Holder
* @param position : position of each Row
* set the values to the views
*/
@Override
public void onBindViewHolder(final TagYourDiseaseAdapter.OrderHistoryViewHolder holder, final int position) {
Picasso.with(mContext).load(deviceList.get(position).getIconUrl()).into(holder.document);
holder.name.setText(deviceList.get(position).getDiseaseName());
holder.radioButton.setOnCheckedChangeListener(null);
holder.radioButton.setChecked(deviceList.get(position).isChecked());
//if true, your checkbox will be selected, else unselected
//holder.radioButton.setChecked(objIncome.isSelected());
holder.radioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
deviceList.get(position).setChecked(isChecked);
}
});
}
@Override
public int getItemCount() {
return deviceList.size();
}
/**
* Create The view First Time and hold for reuse
* View Holder for Create and Hold the view for ReUse the views instead of create again
* Initialize the views
*/
public class OrderHistoryViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView document;
TextView name;
CheckBox radioButton;
public OrderHistoryViewHolder(View itemView) {
super(itemView);
document = itemView.findViewById(R.id.img_tag);
name = itemView.findViewById(R.id.text_tag_name);
radioButton = itemView.findViewById(R.id.rdBtn_tag_disease);
radioButton.setOnClickListener(this);
//this.setIsRecyclable(false);
}
@Override
public void onClick(View view) {
mRecyclerViewItemClickListener.onItemClickListener(this.getAdapterPosition(), view);
}
}
}
이것은 setOnCheckedChangeListener
그 사용 대신에 사용 setObClickListener
하고 내부 에서이 쉬운 핸들을 할 때 발생합니다 .
if (list.get(position).isCheck())
{
list.get(position).setCheck(false);
}
else
{
list.get(position).setCheck(true);
}
참고 : 목록 모델에서 이름이있는 하나의 부울 변수를 추가
check
하고 getter 및 setter를 설정하십시오.
도움이된다면 +이 답변에 투표하세요
배열을 사용하여 항목 상태 유지
어댑터에서 Map 또는 SparseBooleanArray (지도와 유사하지만 int 및 boolean의 키-값 쌍)를 사용하여 항목 목록에있는 모든 항목의 상태를 저장 한 다음 키와 값을 사용하여 비교할 수 있습니다. 체크 된 상태를 전환 할 때
어댑터에서 SparseBooleanArray
// sparse boolean array for checking the state of the items
private SparseBooleanArray itemStateArray= new SparseBooleanArray();
그런 다음 항목 클릭 처리기 onClick()
에서 itemStateArray의 항목 상태를 사용하여 토글하기 전에 확인합니다. 여기에 예제가 있습니다.
@Override
public void onClick(View v) {
int adapterPosition = getAdapterPosition();
if (!itemStateArray.get(adapterPosition, false)) {
mCheckedTextView.setChecked(true);
itemStateArray.put(adapterPosition, true);
}
else {
mCheckedTextView.setChecked(false);
itemStateArray.put(adapterPosition, false);
}
}
또한 희소 부울 배열을 사용하여 뷰가 바인딩 될 때 확인 된 상태를 설정합니다.
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(position);
}
@Override
public int getItemCount() {
if (items == null) {
return 0;
}
return items.size();
}
void loadItems(List<Model> tournaments) {
this.items = tournaments;
notifyDataSetChanged();
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
CheckedTextView mCheckedTextView;
ViewHolder(View itemView) {
super(itemView);
mCheckedTextView = (CheckedTextView) itemView.findViewById(R.id.checked_text_view);
itemView.setOnClickListener(this);
}
void bind(int position) {
// use the sparse boolean array to check
if (!itemStateArray.get(position, false)) {
mCheckedTextView.setChecked(false);}
else {
mCheckedTextView.setChecked(true);
}
}
최종 어댑터는 다음과 같습니다.
나는 사용하지 않는 것이 좋습니다 checkBox.setOnCheckedChangeListener
에서 recyclerViewAdapter
. 스크롤 checkBox.setOnCheckedChangeListener
할 때 recyclerView 가 어댑터에 의해 시작되기 때문입니다. 안전하지 않습니다 . 대신 checkBox.setOnClickListener
사용자 입력과 상호 작용하는 데 사용하십시오.
예를 들면 :
public void onBindViewHolder(final ViewHolder holder, int position) {
/*
.
.
.
.
.
.
*/
holder.checkBoxAdapterTasks.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean isChecked = holder.checkBoxAdapterTasks.isChecked();
if(isChecked){
//checkBox clicked and checked
}else{
//checkBox clicked and unchecked
}
}
});
}
나를 위해 일한 것은 뷰가 재활용 될 때 viewHolder의 리스너를 무효화하는 것입니다 ( onViewRecycled
).
override fun onViewRecycled(holder: AttendeeViewHolder) {
super.onViewRecycled(holder)
holder.itemView.hasArrived.setOnCheckedChangeListener(null);
holder.itemView.edit.setOnClickListener { null }
}
'Nice programing' 카테고리의 다른 글
식별 및 식별되지 않는 관계에 대해 여전히 혼란 스러움 (0) | 2020.10.20 |
---|---|
C에서 단항 '+'연산자의 목적은 무엇입니까? (0) | 2020.10.20 |
긴 16 진수 문자열에서 파이썬 바이트 객체를 만드는 방법은 무엇입니까? (0) | 2020.10.20 |
Android-HashMap에서 값 가져 오기 (0) | 2020.10.20 |
Travis CI의 기능과 사용시기 이해 (0) | 2020.10.19 |