রিসাইক্লারভিউতে চেকবক্স বিভিন্ন আইটেম চেক করে রাখে


93

পুনর্ব্যবহারযোগ্য ভিউয়ের ভিতরে আমার আইটেমগুলির জন্য এখানে এক্সএমএল রয়েছে

<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>

এবং এখানে পুনর্ব্যবহারযোগ্য অ্যাডাপ্টারটি এর প্রতিটি আইটেমের জন্য উপরের লেআউটটিকে স্ফীত করে:

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));
    }
}

সমস্যাটি হ'ল ধরা যাক আমার রিসাইক্লিউউয়ের ভিতরে 10 টি আইটেম রয়েছে। আমি যখন আইটেমটি 1,2,3 এ চেকবক্সটি চেক করেছি তখন আমি রিসাইক্লারভিউটি নীচে স্ক্রোল করি, হঠাৎ করে অন্যান্য আইটেমগুলির মধ্যে যেমন 8,9 আইটেমগুলি চেক করা হয়। এবং আমি যখন আবার স্ক্রোল করব তখন আইটেম 1 এবং 3 টি চেক করা হয় তবে আইটেম 2 নয় Any কোনও ধারণা কেন এটি ঘটে?


এই লাইব্রেরিটি ব্যবহার করার চেষ্টা করুন , ভিউস্টেটস দেখুন। স্ক্রোল করার সময় এটি কোনও রাষ্ট্র সংরক্ষণ করতে সহায়তা করে।
ভিটালি

উত্তর:


167

এটি একটি প্রত্যাশিত আচরণ। আপনি আপনার চেকবক্সটি নির্বাচিত করছেন বা নির্বাচিত করছেন না। আপনি একটি নির্বাচন করছেন এবং দেখুন ধারক এটি নির্বাচিত রাখে। আপনি নিজের অবজেক্ট ইনকাম অবজেক্টে বুলিয়ান ভেরিয়েবল যুক্ত করতে পারেন এবং আপনার আইটেমের নির্বাচনের স্থিতি রাখতে পারেন।

আপনি আমার উদাহরণ তাকান হতে পারে। আপনি এর মতো কিছু করতে পারেন:

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);
            }
        });

    }
}

19
এটি কাজ করে না। আপনাকে holder.cbSelect.setOnCheckedChangeListener(null);আগে লিখতে হবেholder.cbSelect.setChecked(objIncome.isSelected())
জেমশিট ইস্কেনডেরভ

4
কেন হোল্ডার.সি.বি.সিলেক্ট.সেটঅনচেকড চ্যাঞ্জলিস্টনার (নাল) সেট করার কোনও কারণ রয়েছে; কাজ?
দেব

4
@oguzhand হাই আমি আপনার সমাধানটি চেষ্টা করেছি কিন্তু এটি কোনওভাবেই কাজ করছে না: শ্রোতাদের শূন্য করতে বা ছাড়াই।
আব্বাস

4
@oguzhand কোডটি এখানে থেকে onBindViewHolder@Override public void onBindViewHolder(final ItemHolder holder, int position) { holder.checkBox.setOnCheckedChangeListener(null); holder.checkBox.setSelected(list.get(position).isSelected()); holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { list.get(holder.getAdapterPosition()).setSelected(isChecked); } });
আব্বাস

4
@ সুয়েস আপনার কোনও সামগ্রীতে চেকবক্সের স্ট্যাটাস রাখা দরকার কারণ ভিউহোল্ডার কেবল একটি ধারক। আপনার যদি 100 টি আইটেম থাকে তবে আপনার কাছে প্রায় 6-7 আছে (স্ক্রিন এবং লেআউট আকারের উপর নির্ভর করে) ভিউহোল্ডারগুলি থাকে এবং এই সমস্ত অবজেক্টটিকে একটি চক্র ব্যবহার করে।
ওউজান ডাঙ্গেল

22

সংক্ষেপে, এর কারণগুলি পুনরুদ্ধার করা হয়েছে এবং আবার ব্যবহার করার জন্য!

কীভাবে আপনি এড়াতে পারেন:

1. onBindViewHolderআপনার বাক্সগুলি পরীক্ষা করা বা চেক করা উচিত কিনা তা পরীক্ষা করে দেখুন। দুটি এবং অন্যথায় রাখতে ভুলবেন না

if (...)
    holder.cbSelect.setChecked(true);
else
    holder.cbSelect.setChecked(false);
  1. চেক বক্সের জন্য একটি শ্রোতা রাখুন! যখনই এর চেক করা মূর্তিগুলি পরিবর্তিত হবে, তখন আপনার myItemsঅ্যারেতেও সম্পর্কিত বিষয়টিকে আপডেট করুন ! সুতরাং যখনই কোনও নতুন দৃশ্য প্রদর্শিত হবে, তখন এটি বস্তুর সর্বাধিক মূর্তিটি পড়ে।

আপনার দ্বিতীয় পয়েন্ট মূল ছিল। যদিও এটি একটি পরিস্থিতিতে সবচেয়ে ভাল কাজ করে, যখন প্রাথমিক ডেটাসেটেও পরীক্ষিত রাষ্ট্র সম্পর্কে তথ্য থাকে (যা আমার ক্ষেত্রে এটি)
আটটিলা ওরোজ

4
এটি হল আরও সোজা-থেকে-পয়েন্ট এবং সঠিক উত্তর। উভয় সত্য এবং onBindViewHolder মিথ্যা জন্য SetCheck চাবিকাঠি
Beeing Jk

আমার ক্ষেত্রে, আমি ডিফল্ট মান সঙ্গে তথ্য মডেল ডাটা সংরক্ষণ করতে হবে isChecked falseশুরু সমস্ত ডেটা সেট, তারপর onCheckChangedআমি শুধু আপডেট isCheckedমান trueবা falseএবং উত্তরে বলেন বাস্তবায়ন যে চেক পারেন চেক করা বা না।
আলী তমুর

20

কেবলমাত্র এটি ব্যবহার করুন যদি আপনার রিসাইক্লার দর্শনে সীমিত সংখ্যক আইটেম থাকে।
আমি মডেলটিতে বুলিয়ান মান ব্যবহার করার চেষ্টা করেছি এবং চেকবক্সের স্থিতি রাখি, তবে এটি আমার ক্ষেত্রে সহায়তা করে নি। আমার জন্য যা কাজ করেছে তা হ'ল এই .setIsRecyclala (মিথ্যা);

public class ComponentViewHolder extends RecyclerView.ViewHolder {
    public MyViewHolder(View itemView) {
        super(itemView);
        ....
        this.setIsRecyclable(false);
    }

এ সম্পর্কে আরও ব্যাখ্যা এখানে পাওয়া যাবে https://developer.android.com/references/android/support/v7/widget/RecyclerView.ViewHolder.html#isRecyclalable ()

দ্রষ্টব্য: এটি একান্ত কার্যনির্বাহী। এটি যথাযথভাবে ব্যবহার করতে আপনি ডকুমেন্টটি উল্লেখ করতে পারেন যা "সেটসাইসাইকাইলেবল () এর কলগুলি সর্বদা যুক্ত করা উচিত (সেটসআইসিসাইক্লেবে (মিথ্যা) তে একটি কলটি সবসময় মিলানো উচিত সেটসইসাইক্য্যাকলেবল (সত্য)) এর সাথে পরবর্তী কলের সাথে মিল থাকা উচিত calls , যেমন রাষ্ট্রটি অভ্যন্তরীণভাবে রেফারেন্স-গণনা করা হয়। আমি কোডে এটি কীভাবে করব তা আমি জানি না, যদি কেউ এই বিষয়ে আরও কোড সরবরাহ করতে পারে।


দয়া করে আপনি এটি কীভাবে ব্যবহার করবেন তা ব্যাখ্যা করতে পারেন?
ব্যবহারকারীর

44
এটি কি রিসাইকেলারভিউয়ের পিছনে যুক্তির অপচয় নয়?
এরেন

4
আমি এটি দীর্ঘ তালিকা দিয়ে চেষ্টা করেছি যা এলোমেলো চেক করার সমস্যার সমাধান করেছে তবে যখন আমি নীচে স্ক্রোল করে লম্বা তালিকার সাথে আবার স্ক্রোল করব তখন চেক করা চেকবক্সগুলি অদৃশ্য হয়ে যায় :(
সোনডাং

4
দর্শনটি অবিস্মরণীয় করা ভাল ধারণা নয় কারণ এটি স্মৃতিশক্তি হ্রাস করবে এবং আপনি পুনর্ব্যবহারযোগ্য দর্শনের বেশিরভাগ সুবিধা হারাবেন।
আর্থার

আমি আপনার সাথে একমত, @ এরেন130 এবং আর্থার। আমি পোস্টটি সম্পাদনা করেছি, এবং যদি আমরা সেটআইসাইক্রাইলেবল (সত্য / মিথ্যা) ব্যবহার করার উপায় নিয়ে আসতে পারি তবে অনেক প্রশংসা করব; সঠিকভাবে
রানা রণভিজয় সিংহ

13

এর দুটি ওভাররাইড পদ্ধতি যুক্ত করুন RecyclerView

@Override
public long getItemId(int position) {
    return position;
}

@Override
public int getItemViewType(int position) {
    return position;
}

4
তা করবেন না !! এটি পুনর্ব্যবহারযোগ্য ভিউ পুনর্ব্যবহারযোগ্য প্রক্রিয়াটিকে বাইপাস করবে এবং এটি ব্যবহারের পুরো পয়েন্টটি হারাবে।
হ্যানোক মোরেনো

4
না এটি হবে না, এটি কেবল ভিউ ধারকটির প্রতিটি পুনর্ব্যবহৃত দৃশ্যের সঠিক অবস্থানটি প্রদান করে।
হরিশ রেড্ডি

4
হরিশ, সম্ভবত আমি কিছু মিস করছি, তবে যতদূর আমি জানি, এটি করার মাধ্যমে আপনি আসলে অ্যাডাপ্টারকে বলবেন যে আইটেমের ধরণের সংখ্যা হ'ল আইটেম গণনা। অর্থটি হ'ল কোনও আইটেম পুনর্ব্যবহারযোগ্য করা যায় না কারণ এতে কোনও সিমিলার ভিউ নেই। যদিও এটি পরীক্ষা করা সহজ। অনবিন্দ ভিউহোল্ডারটির ভিতরে কেবল ভিউহোল্ডার.ইটিএমভিউ রেফারেন্স লগ করুন এবং দেখুন একই ভিউ রেফারেন্স ধারণ করে দুটি ভিউহোল্ডার রয়েছে কিনা। পরীক্ষাটি দীর্ঘ তালিকাতে থাকা উচিত তাই পুনর্ব্যবহারযোগ্য সিস্টেমটি কার্যকর করা হবে।
হ্যানোচ মোরেনো

4
এটি নির্দোষভাবে জেগেছিল, এটি আমার দিনকে বাঁচিয়েছিল।
কুন্ডন

4
আপনার রিসাইক্লারভিউতে আপনার যদি 100 এর বেশি আইটেম থাকে তবে এই দ্রবণটি সমস্ত আইটেম একবারে লোড করবে, আপনার ছবিগুলির ক্ষেত্রে যদি এই চিত্রটি বোঝায় তবেই সমাধানটি সঠিক হতে পারে @ কুন্ডন
হরিশ রেড্ডি

11

প্রতিটি পুনর্ব্যবহারযোগ্য আইটেমের চেকবক্সটি ট্র্যাক রাখতে আপনি মডেল ক্লাস ব্যবহার করতে পারেন। সম্পূর্ণ রেফারেন্সটি হ'ল: রিসাইক্লারভিউ চেকবক্স অ্যান্ড্রয়েড

চেকবক্সের স্থিতি রাখার জন্য সেটট্যাগ এবং গেটটাগ ব্যবহার করা হয়। আরও তথ্যের জন্য সম্পূর্ণ রেফারেন্স লিংক চেক করুন। এটি চেক করা আইটেমগুলি কীভাবে পাঠাতে হবে তা শিখায়

নকশা তৈরি কর

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;
    }
}

পূর্ণসংখ্যা.এক্সএমএল তৈরি করুন

<?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);
    }

}

}


3

Kotlin একমাত্র জিনিস যা আমার জন্য এই সমস্যার সমাধান ব্যবহার পরিষ্কার ছিল OnCheckedChangeListenerপরিবর্তনশীল সংযোজনা করার আগে এবং তারপর একটি নতুন OnCheckedChangeListenerপর checkedসেট করা হয়েছে।

আমি আমার নিম্নলিখিত নিম্নলিখিত RecyclerView.ViewHolder

task.setOnCheckedChangeListener(null)
task.isChecked = item.status
task.setOnCheckedChangeListener { _: CompoundButton, checked: Boolean ->
    item.status = checked
    ...
    do more stuff
    ...
}

এটি নিখুঁতভাবে কাজ করছে। আমি তা করি না তবে এটি কেবল তখনই কাজ করে যখন কেউ কটলিন ব্যবহার করে!
আদিত্য এস।

2

উপরে বর্ণিত হিসাবে, অবজেক্টের চেক করা রাষ্ট্রটি বস্তুর বৈশিষ্ট্যের মধ্যে অন্তর্ভুক্ত করা উচিত। কিছু ক্ষেত্রে আপনার নিজের অবজেক্টটিতে ক্লিক করে অবজেক্ট সিলেকশন রাষ্ট্র পরিবর্তন করার প্রয়োজন হতে পারে এবং চেকবক্সকে প্রকৃত অবস্থা (নির্বাচিত বা না নির্বাচিত) সম্পর্কে জানাতে দিন। তারপরে চেকবক্সটি প্রদত্ত অ্যাডাপ্টারের আসল অবস্থানে যা বস্তুর অবস্থার ব্যবহার করবে (যা ডিফল্টরূপে / বেশিরভাগ ক্ষেত্রে) তালিকার উপাদানটির অবস্থান।

নীচে স্নিপেট পরীক্ষা করুন, এটি দরকারী হতে পারে।

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);

        }
    }
}



2

আইটেমগুলির স্থিতি ধরে রাখতে একটি অ্যারে ব্যবহার করুন

অ্যাডাপ্টারে আমাদের আইটেমের তালিকায় সমস্ত আইটেমের অবস্থা সংরক্ষণ করতে মানচিত্র বা স্পার্সবুলিয়ানআরে (যা মানচিত্রের অনুরূপ তবে ইনট এবং বুলিয়ান একটি মূল-মান জুড়ি) ব্যবহার করুন এবং তারপরে কীগুলি এবং মানগুলি তুলনা করতে ব্যবহার করুন চেক করা অবস্থায় টগল করার সময়

অ্যাডাপ্টারে একটি তৈরি করুন SparseBooleanArray

// sparse boolean array for checking the state of the items

    private SparseBooleanArray itemStateArray= new SparseBooleanArray();

তারপরে আইটেম ক্লিক onClick()ক্লিককারী হ'ল টগল করার আগে চেক করতে আইটেমস্টেটআর্রে আইটেমগুলির স্থিতি ব্যবহার করুন, এখানে একটি উদাহরণ

        @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);
        }
    }

এবং চূড়ান্ত অ্যাডাপ্টারের মতো হবে এই


1

আপনাকে চেকবক্সের সাথে বাইন্ড ভিউহোল্ডার (যুক্তি) এবং ইন্টারঅ্যাকশন পৃথক করতে হবে check আমি যুক্তির জন্য ব্যবহারকারীর মিথস্ক্রিয়া (স্পষ্টতই) এবং ভিউহোল্ডার.বাইন্ড () ব্যবহার করে অনচেকড চ্যাঞ্জলিস্টনার ব্যবহার করেছি, তবে ধারককে সেট আপ করার আগে এবং ধারক প্রস্তুত হওয়ার পরে আপনাকে চেক শ্রোতাদের কেন বাতিল করতে হবে - ব্যবহারকারীর ইন্টারঅ্যাকশনগুলির জন্য চেক শ্রোতাদের কনফিগার করতে হবে।

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);
            }
        }

1

আমি সুপারিশ করছি যে ব্যবহার না করার checkBox.setOnCheckedChangeListenerমধ্যে recyclerViewAdapter। কারণ স্ক্রোলিং রিসাইক্লারভিউতে checkBox.setOnCheckedChangeListenerঅ্যাডাপ্টারের মাধ্যমে বরখাস্ত করা হবে। এটা নিরাপদ নয় । পরিবর্তে, ব্যবহার করুন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
                }

            }
        });

    }

1

এই সমাধানটির যে সমস্যাটি আমি পেয়েছি তা হ'ল স্থির বৈশ্বিক অ্যারে তৈরি করে এবং এটি "অনবাইন্ডহোল্ডার" অ্যাডাপার ক্লাসে ব্যবহার করে, যাতে আমি প্রয়োজনীয় সমস্ত বৈকল্পিক / বস্তু তৈরি করেছি।

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);

        }

    }

}

এখানে (রেভাডাপ্টারের ক্লাসের নির্মাতা) আমি অ্যারেটিকে আকার দিয়েছি আইটেমের / না আকারের সমান যা আমি পুনর্ব্যবহারকারী দৃশ্যে প্রদর্শন করতে যাচ্ছি

List<Person> persons;

RVAdapter(List<Person> persons){
    this.persons = persons;
    PersonViewHolder.check=new int[persons.size()];
    PersonViewHolder.k=persons.size();
}

বিনডভিউহোল্ডার, আমি, এই ধারণাকে একটি বোতামে প্রয়োগ করেছি, যখন আমি একটি বোতামে ক্লিক করি, তখন বোতামটির পটভূমি চিত্র পরিবর্তন হয়। আমি যে বোতামটি ব্যবহার করেছি তা হ'ল নামগুলি "আপভোট" হিসাবে, যেমন "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);
    }

}

1

আমি একই সমস্যা ছিল। আমি যখন আমার পুনর্ব্যবহারকারীতে আইটেমের টগল বোতামে ক্লিক করছিলাম তখন টগল বোতামটি প্রতি দশম আইটেমে উপস্থিত হয়েছিল (উদাহরণস্বরূপ যদি এটি 0 সূচকযুক্ত আইটেমটিতে ক্লিক করা হয়, 9, 18, 27 সূচকযুক্ত আইটেমগুলিও ক্লিক করা হয়েছিল)। প্রথমত, অনবিন্দ ভিহোল্ডারটিতে আমার কোডটি ছিল:

if (newsItems.get(position).getBookmark() == 1) {
            holder.getToggleButtonBookmark().setChecked(true);
        }

তবে আমি অন্য বিবৃতি যুক্ত

if (newsItems.get(position).getBookmark() == 1) {
            holder.getToggleButtonBookmark().setChecked(true);
//else statement prevents auto toggling
        } else{
            holder.getToggleButtonBookmark().setChecked(false);
        }

এবং সমস্যা সমাধান করা হয়েছিল


ধন্যবাদ. অন্য অংশটি একই ভিউটি পুনর্ব্যবহার করার সময় ডিফল্টরূপে চেক করে থাকলে চেকবক্সটি সাফ করবে।
আদর্শ বিজয়ন পি

1

ঠিক আছে এখানে অনেক উত্তর আছে আমি আমার কোড পোস্ট করব এবং আমি কী করলাম তা কেবল ব্যাখ্যা করব ... এটি আমার মতো জুনিয়রকে সাহায্য করতে পারে: ডি।

1- উদ্দেশ্য:

আমরা একটি তালিকার তৈরি করবে RecyclerViewযে হয়েছে CheckBoxএবং RadioButtonভালো কিছু:

এখানে চিত্র বর্ণনা লিখুন 2- মডেল ক্লাস

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-আমার অ্যামেজিং অ্যাডাপ্টার

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();
                    }
                });

0

আমার একটি পুনর্ব্যবহারযোগ্য ভিউ তালিকায় সুইচগুলির সাথে একই সমস্যা ছিল এবং @oguzhand উত্তরটি ব্যবহার করে এটি সমাধান করা হয়েছে তবে চেকড চ্যাঞ্জলিস্টারের ভিতরে এই কোডটি দিয়ে:

if (buttonView.isPressed()) {
    if (isChecked) {
        group.setSelected(true);
    } else {
        group.setSelected(false);
    }
}else{
    if (isChecked) {
        buttonView.setChecked(false);
    } else {
        buttonView.setChecked(true);
    }
}

(যেখানে 'গোষ্ঠী' হ'ল সেই সত্তা যেখানে আমি নির্বাচন / নির্বাচন নির্বাচন করতে চাই)


0

পাবলিক ক্লাস TagYourDiseaseAdapter রেসাইক্লার ভিউ অ্যাডাপ্টার প্রসারিত {ব্যক্তিগত রেসাইক্লারভিউ আইটেম ক্লিকলিস্টনার প্রাইভেট কনটেক্সট এম কনটেক্সট;

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);
    }
}

}


0

যখন এটি ব্যবহারের setOnCheckedChangeListenerপরিবর্তে ব্যবহার হবে setObClickListenerএবং অভ্যন্তরে কেবল এই সহজ হ্যান্ডেলটি করুন তখন এটি ঘটবে :

   if (list.get(position).isCheck())
            {
                list.get(position).setCheck(false);
            }
            else
            {
                list.get(position).setCheck(true);
            }

দ্রষ্টব্য: আপনার তালিকার মডেলটিতে নাম checkএবং সেট গেটর এবং সেটারের সাথে একটি বুলিয়ান ভেরিয়েবল যুক্ত করুন , উপরের ক্ষেত্রে আমার সেট সেট এবং চেক হয়

আশা করি এটি কারওর কাছে সহায়তা করলে এই উত্তরটিতে ভোট দিন


0

যোগ করার পদ্ধতি setItemViewCacheSize (int- আকারের) recyclerview প্রয়োজন এবং তালিকার আকার ক্ষণস্থায়ী আমার সমস্যার সমাধান।

মাইকোড:

mrecyclerview.setItemViewCacheSize(mOrderList.size());
mBinding.mrecyclerview.setAdapter(mAdapter);

সূত্র: https://stackoverflow.com/a/46951440/10459907


0

এটি বার বার ভিউ তৈরির কারণে, অ্যাডাপ্টার সেট করার আগে সেরা বিকল্পটি পরিষ্কার ক্যাশে

recyclerview.setItemViewCacheSize(your array.size());

0

সম্পূর্ণ উদাহরণ
পাবলিক ক্লাসের চাইল্ডএড্রেস অ্যাডাপ্টার রিসাইক্লার ভিউ অ্যাডাপ্টার প্রসারিত করে <চাইল্ডএড্রেস অ্যাডাপ্টার.কার্টভিউহোল্ডার> {

private Activity context;
private List<AddressDetail> addressDetailList;
private int selectedPosition = -1;

public ChildAddressAdapter(Activity context, List<AddressDetail> addressDetailList) {
    this.context = context;
    this.addressDetailList = addressDetailList;
}

@NonNull
@Override
public CartViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    LayoutInflater inflater = LayoutInflater.from(context);
    View myView = inflater.inflate(R.layout.address_layout, parent, false);
    return new CartViewHolder(myView);
}

@Override
public void onBindViewHolder(@NonNull CartViewHolder holder, int position) {

    holder.adress_checkbox.setOnClickListener(view -> {
        selectedPosition = holder.getAdapterPosition();
        notifyDataSetChanged();
    });

    if (selectedPosition==position){
        holder.adress_checkbox.setChecked(true);
    }
    else {
        holder.adress_checkbox.setChecked(false);
    }


}

@Override
public int getItemCount() {
    return  addressDetailList.size();
}

class CartViewHolder extends RecyclerView.ViewHolder
{
    TextView address_text,address_tag;
    CheckBox adress_checkbox;

    CartViewHolder(View itemView) {
        super(itemView);
        address_text = itemView.findViewById(R.id.address_text);
        address_tag = itemView.findViewById(R.id.address_tag);
        adress_checkbox = itemView.findViewById(R.id.adress_checkbox);
    }
}

}


-1

আমার পক্ষে কাজটি হ'ল ভিউহোল্ডারটিতে শ্রোতাদের বাতিল করতে হবে যখন ভিউটি পুনর্ব্যবহার করা হবে ( onViewRecycled):

 override fun onViewRecycled(holder: AttendeeViewHolder) {
            super.onViewRecycled(holder)
            holder.itemView.hasArrived.setOnCheckedChangeListener(null);
            holder.itemView.edit.setOnClickListener { null }
        }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.