অ্যান্ড্রয়েড পুনর্ব্যবহারযোগ্য ভিউ: notifDataSetChanged () অবৈধ স্টেটএক্সসেপশন


130

আমি notifyDataSetChanged () ব্যবহার করে একটি পুনর্ব্যবহারের আইটেমগুলি আপডেট করার চেষ্টা করছি।

এটি রিসাইক্যভিউ অ্যাডাপ্টারে আমার অনবিন্দ ভিউহোল্ডার () পদ্ধতি।

@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {

     //checkbox view listener
    viewHolder.getCheckbox().setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

            //update list items
            notifyDataSetChanged();
        }
    });
}

আমি যা করতে চাই তা হল তালিকার আইটেমগুলি আপডেট করা, আমি একটি চেকবাক্স চেক করার পরে। যদিও আমি একটি অবৈধ ব্যতিক্রম পাই:"Cannot call this method while RecyclerView is computing a layout or scrolling"

java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling
    at android.support.v7.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:1462)
    at android.support.v7.widget.RecyclerView$RecyclerViewDataObserver.onChanged(RecyclerView.java:2982)
    at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:7493)
    at android.support.v7.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:4338)
    at com.app.myapp.screens.RecycleAdapter.onRowSelect(RecycleAdapter.java:111)

আমি notifIteChanged () একই ব্যতিক্রম ব্যবহার করেছি। অ্যাডাপ্টারকে আপডেট করার কোনও আপডেট গোপনীয় উপায় যা কিছু বদলেছে?


আমি এখন এই একই সমস্যা হচ্ছে। ভিউহোল্ডার কনস্ট্রাক্টরে সেটচেনচেনড শ্রোতাদের স্থাপন করা আমাকে একই ত্রুটি দেয়
ফিলিটি_উইজার্ড

উত্তর:


145

আপনার অ্যাডাপ্টারের অভ্যন্তর শ্রেণীর ভিউহোল্ডারটিতে আপনার পদ্ধতি 'setOnCheckedChangeListener ()' সরানো উচিত।

onBindViewHolder()আরম্ভ করার পদ্ধতি নয় ViewHolder। এই পদ্ধতিটি প্রতিটি পুনর্ব্যক্তকারী আইটেমকে রিফ্রেশ করার পদক্ষেপ। আপনি কল যখন notifyDataSetChanged(), onBindViewHolder()প্রতিটি আইটেমের যতবার যেমন ডাকা হবে।

সুতরাং আপনি যদি চেকবক্সটি notifyDataSetChanged()প্রবেশ করে onCheckChanged()আরম্ভ করেন onBindViewHolder(), তবে বিজ্ঞপ্তি পদ্ধতি কলের কারণে আপনি ইলিজেলস্টেট এক্সসেপশন পাবেন।

চেকবাক্স ক্লিক করুন -> onCheckedChanged () -> notifyDataSetChanged () -> onBindViewHolder () -> চেকবক্স সেট করুন -> onChecked ...

সহজভাবে, আপনি অ্যাডাপ্টারে একটি পতাকা রেখে এটি ঠিক করতে পারেন।

এটা চেষ্টা কর,

private boolean onBind;

public ViewHolder(View itemView) {
    super(itemView);
    mCheckBox = (CheckBox) itemView.findViewById(R.id.checkboxId);
    mCheckBox.setOnCheckChangeListener(this);
}

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    if(!onBind) {
        // your process when checkBox changed
        // ...

        notifyDataSetChanged();
    }
}

...

@Override
public void onBindViewHolder(YourAdapter.ViewHolder viewHolder, int position) {
    // process other views 
    // ...

    onBind = true;
    viewHolder.mCheckBox.setChecked(trueOrFalse);
    onBind = false;
}

আমি দেখছি, বোধ হয়। প্ল্যাটফর্ম ইচ্ছা যেমন সহজ আচরণ ভবিষ্যদ্বাণী করা হবে এবং পতাকা উপর নির্ভর করতে হচ্ছে পরিবর্তে একটি সমাধান দিতে ..
আর্থার

AdapterViewObserverযতক্ষণ onBindViewHolder()আপনি অগ্রগতির সময় অবহিত না করে আপনি শ্রোতাদের কোথায় সেট করেছেন তা বিবেচ্য নয় ।
ইয়ারোস্লাভ মাইটকলিক

6
আমি মন্তব্যে কিছু উন্নতি করে এই সমাধানটি stackoverflow.com/a/32373999/1771194 পছন্দ করি । এটি আমাকে পুনর্ব্যবহারযোগ্য ভিউতে "রেডিওগ্রুপ" তৈরি করার অনুমতিও দিয়েছে।
আর্টেম

আমি কীভাবে আমার তালিকায় আইটেম পোস্ট করব?
ফিলিটি_উইজার্ড

2
এটি দর্শকের মধ্যে আমার পক্ষে কাজ করে না। এখনও ক্র্যাশ ত্রুটি পেতে। অ্যারেলিস্টে আমার ভার্স বদলাতে হবে। খুব অদ্ভুত. খুব বেশি নিশ্চিত নয় যে আমি তালিকাটি সংযুক্ত করতে পারি।
ফিলিটি_উইজার্ড 10

45

আপনি পরিবর্তনগুলি করার আগে আপনি কেবল পূর্বের শ্রোতাকে পুনরায় সেট করতে পারেন এবং আপনি এই ব্যতিক্রমটি পাবেন না।

private CompoundButton.OnCheckedChangeListener checkedListener = new CompoundButton.OnCheckedChangeListener() {                      
                        @Override
                        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                            //Do your stuff
                    });;

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        holder.checkbox.setOnCheckedChangeListener(null);
        holder.checkbox.setChecked(condition);
        holder.checkbox.setOnCheckedChangeListener(checkedListener);
    }

2
ভাল উত্তর, তবে প্রতিটি অনবিন্দ ভিহোল্ডার কলটিতে শ্রোতা তৈরি না করাই ভাল। এটি একটি ক্ষেত্র হিসাবে তৈরি করুন।
আর্টেম 11

1
ক্ষেত্র ব্যবহার করা অবশ্যই আরও ভাল, আমি কেবল একটি উদাহরণ দিচ্ছিলাম যা কাজ করে। তবে সতর্কতার জন্য ধন্যবাদ, আমি উত্তরটি আপডেট করব।
JoniDS

1
আমার প্রকৃতপক্ষে প্রতিবারই নতুন শ্রোতার সাথে আবদ্ধ হওয়া দরকার কারণ শ্রোতার প্রত্যেকবার একটি আপডেট অবস্থানের পরিবর্তনশীল প্রয়োজন। সুতরাং এটি দুর্দান্ত উত্তর তাই আমাকে কোনও হ্যান্ডলার ব্যবহার করতে হবে না।
রক লি

এটি অবশ্যই এটি করার সর্বোত্তম উপায় কারণ এটি বৈশ্বিক রাষ্ট্র রাখার জন্য কখনই সুপারিশ করা হয় না, যা গ্রহণযোগ্য উত্তর ( স্ট্যাকওভারফ্লো . com / a / 31069171 / 882251 ) সুপারিশ করছে।
দারউইন্ড

সিম্পল এক !! ধন্যবাদ !!
দলভীরসিংহডাইয়া 29:18

39

Handlerআইটেম যুক্ত করার জন্য এটি ব্যবহার করা এবং এটি notify...()থেকে কল করা Handlerআমার জন্য সমস্যাটি স্থির করে।


3
এটি সঠিক উত্তর, এটি সেট করার সময় আপনি আইটেমটি পরিবর্তন করতে পারবেন না (অনবিন্দ ভিউহোল্ডারকে কল করার সাথে)। যে ক্ষেত্রে আপনাকে কল Handler.post () করে বর্তমান লুপ শেষে notifyDataSetChanged ফোন করতে হবে
pjanecze

1
@ ব্যবহারকারী 1232726 আপনি যদি প্রধান থ্রেডে হ্যান্ডলারটি তৈরি করেন তবে আপনাকে কোনও লুপার নির্দিষ্ট করতে হবে না (কলিং থ্রেড লুপারের ডিফল্ট)। হ্যাঁ, এটি আমার পরামর্শ। অন্যথায় আপনি নিজেও লুপারটি নির্দিষ্ট করতে পারেন।
সাইবারজেন

দুর্ভাগ্যক্রমে আমার চেকবক্সগুলি যখন আমি নীচে স্ক্রোল করব এবং আবার ব্যাক আপ করলাম তখন তা চেক থাকবে না। বু। lol
অশ্লীল_ উইজার্ড

@ ব্যবহারকারী 1232726 একটি উত্তর অনুসন্ধান করুন বা আপনার সমস্যা বর্ণনা করে একটি নতুন প্রশ্ন জিজ্ঞাসা করুন।
সাইবারজেন

2
আমি এই উত্তরটিকে দৃ strongly়ভাবে নিরুৎসাহিত করব কারণ সমস্যাটি সমাধানের এটি একটি হ্যাকি উপায়। আরও আপনি আরও এটি করতে আপনার কোড বুঝতে জটিল হয়ে ওঠে। পড়ুন Moonsoo এর উত্তর সমস্যা ও বুঝতে JoniDS এর সমস্যা সমাধানের জন্য উত্তর।
কল্পনা প্যাটেল

26

আমি ভাল জানি না, তবে আমারও একই সমস্যা ছিল। আমি onClickListnerএটি ব্যবহার করে সমাধান করেছিcheckbox

viewHolder.mCheckBox.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (model.isCheckboxBoolean()) {
                model.setCheckboxBoolean(false);
                viewHolder.mCheckBox.setChecked(false);
            } else {
                model.setCheckboxBoolean(true);
                viewHolder.mCheckBox.setChecked(true);
            }
            notifyDataSetChanged();
        }
    });

এটি চেষ্টা করুন, এটি সাহায্য করতে পারে!


1
খুব ভাল কাজ) তবে ক্লিক ক্লিক করুন (যদি আমি ধীরে ধীরে উইজেটটি স্যুইচ করি তবে) এই ক্রিয়াটি মিস হবে missedএই একমাত্র সমস্যা
ভ্লাদ

12
protected void postAndNotifyAdapter(final Handler handler, final RecyclerView recyclerView, final RecyclerView.Adapter adapter) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (!recyclerView.isComputingLayout()) {
                    adapter.notifyDataSetChanged();
                } else {
                    postAndNotifyAdapter(handler, recyclerView, adapter);
                }
            }
        });
    }

আমি মনে করি আপনি সহজেই দুবার অ্যাডাপ্টারকে অবহিত করতে পারেন।
Петлюк Петлюк

8

আপনার যখন বার্তার ত্রুটি রয়েছে:

Cannot call this method while RecyclerView is computing a layout or scrolling

সরল, কেবল ব্যতিক্রমের কারণেই করুন:

RecyclerView.post(new Runnable() {
    @Override
    public void run() {
        /** 
        ** Put Your Code here, exemple:
        **/
        notifyItemChanged(position);
    }
});

1
এটি আমার পক্ষে কাজ করেছে। ভাবছেন এই সমাধান নিয়ে কোন সমস্যা আছে কি?
সৈয়ুজ ভালসান

7

একটি সহজ সমাধান খুঁজে পেয়েছি -

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{

    private RecyclerView mRecyclerView; 

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        mRecyclerView = recyclerView;
    }

    private CompoundButton.OnCheckedChangeListener checkedChangeListener 
    = (compoundButton, b) -> {
        final int position = (int) compoundButton.getTag();
        // This class is used to make changes to child view
        final Event event = mDataset.get(position);
        // Update state of checkbox or some other computation which you require
        event.state = b;
        // we create a runnable and then notify item changed at position, this fix crash
        mRecyclerView.post(new Runnable() {
            @Override public void run() {
                notifyItemChanged(position));
            }
        });
    }
}

রিসাইক্লারভিউ হ্যান্ডেল করার জন্য প্রস্তুত হলে আমরা এখানে একটি অবস্থানের জন্য অবহিত করতে আইটেমচেন্জেড তৈরি করি।


5

আপনি যখন কল করবেন তখন আপনার চেকবক্স আইটেমটি আকর্ষণীয় পরিবর্তন notifyDataSetChanged();করতে পারে তাই এই ব্যতিক্রম ঘটবে। notifyDataSetChanged();আপনার দেখার পোস্টে কল চেষ্টা করুন । উদাহরণ স্বরূপ:

buttonView.post(new Runnable() {
                    @Override
                    public void run() {
                        notifyDataSetChanged();
                    }
                });

4

প্রথমে আমি ভেবেছিলাম মুনসুর উত্তর (স্বীকৃত উত্তর) আমার পক্ষে কাজ করবে না কারণ আমি setOnCheckedChangeListener()ভিউহোল্ডার কনস্ট্রাক্টরে আমার আরম্ভ করতে পারি না কারণ আমাকে প্রতিবার এটি আবদ্ধ করা দরকার যাতে এটি একটি আপডেট অবস্থানের পরিবর্তনশীল হয়ে যায়। তবে তিনি কী বলছেন তা বুঝতে আমার অনেক সময় লেগেছে।

এখানে তিনি যে কথা বলছেন "বিজ্ঞপ্তি পদ্ধতি কল" এর একটি উদাহরণ:

public void onBindViewHolder(final ViewHolder holder, final int position) {
    SwitchCompat mySwitch = (SwitchCompat) view.findViewById(R.id.switch);
    mySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                       if (isChecked) {
                           data.delete(position);
                           notifyItemRemoved(position);
                           //This will call onBindViewHolder, but we can't do that when we are already in onBindViewHolder!
                           notifyItemRangeChanged(position, data.size());
                       }
                   }
            });
    //Set the switch to how it previously was.
    mySwitch.setChecked(savedSwitchState); //If the saved state was "true", then this will trigger the infinite loop.
}

এটির সাথে একমাত্র সমস্যাটি হ'ল আমাদের যখন স্যুইচটি চালু বা বন্ধ করার জন্য শুরু করতে হবে (উদাহরণস্বরূপ, পূর্ববর্তী সংরক্ষিত অবস্থা থেকে), এটি শ্রোতাদের কল করছে nofityItemRangeChangedযা onBindViewHolderআবার কল করবে call আপনি onBindViewHolderইতিমধ্যে যখন আছেন তখনই আপনি কল করতে পারবেন না onBindViewHolder], কারণ আপনি notifyItemRangeChangedযদি ইতিমধ্যে আইটেমের পরিসীমা বদলেছে তা জানিয়ে দেওয়ার মাঝামাঝি জায়গায় থাকলে তা করতে পারবেন না । তবে আমার কেবলমাত্র ইউআই আপডেট করতে হবে এটি চালু বা বন্ধ করার জন্য, যা আসলে কোনও ট্রিগার করতে চায় না।

এখানে সমাধানটি আমি জনিডিএসের উত্তর থেকে শিখেছি যা অসীম লুপটিকে আটকাবে। যতক্ষণ আমরা চেক সেট করার আগে শ্রোতাদের "নাল" তে সেট করি, ততক্ষণ এটি অসীম লুপটি এড়িয়ে শ্রোতাদের ট্রিগার না করেই ইউআই আপডেট করবে। তারপরে আমরা শ্রোতাদের পরে সেট করতে পারি।

জোনিডিএসের কোড:

holder.checkbox.setOnCheckedChangeListener(null);
holder.checkbox.setChecked(condition);
holder.checkbox.setOnCheckedChangeListener(checkedListener);

আমার উদাহরণের সম্পূর্ণ সমাধান:

public void onBindViewHolder(final ViewHolder holder, final int position) {
    SwitchCompat mySwitch = (SwitchCompat) view.findViewById(R.id.switch);

    //Set it to null to erase an existing listener from a recycled view.
    mySwitch.setOnCheckedChangeListener(null);

    //Set the switch to how it previously was without triggering the listener.
    mySwitch.setChecked(savedSwitchState); //If the saved state was "true", then this will trigger the infinite loop.

    //Set the listener now.
    mySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                data.delete(position);
                notifyItemRemoved(position);
                //This will call onBindViewHolder, but we can't do that when we are already in onBindViewHolder!
                notifyItemRangeChanged(position, data.size());
            }
        }
    });
}

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

4

নীচে RecyclerView.isComputingLayout()রাজ্য কেন পরীক্ষা করা হচ্ছে না ?

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{

    private RecyclerView mRecyclerView; 

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        mRecyclerView = recyclerView;
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int position) {

        viewHolder.getCheckbox().setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (mRecyclerView != null && !mRecyclerView.isComputingLayout()) {
                    notifyDataSetChanged();
                }
            }
        });
    }
}

2

আইটেমটি লেআউট ম্যানেজারের দ্বারা আবদ্ধ হওয়ার সময়, সম্ভবত আপনি আপনার চেকবক্সের চেক করা অবস্থাটি সেট করছেন যা কলব্যাককে ট্রিগার করছে।

অবশ্যই এটি একটি অনুমান কারণ আপনি পুরো স্ট্যাক ট্রেস প্রকাশ করেন নি।

আরভি লেআউটটিকে পুনরায় গণনা করার সময় আপনি অ্যাডাপ্টার সামগ্রী পরিবর্তন করতে পারবেন না। আইটেমের চেক করা অবস্থা কলব্যাকে প্রেরিত মানের সমান হলে (কলিং কলব্যাকটি ট্রিগার করে থাকলে কেসটি হবে) যদি আপনি বিজ্ঞপ্তি ডেটাসেট চেঞ্জ না করে এড়াতে পারেন checkbox.setChecked


ধন্যবাদ @ ইজিট! আমার ইস্যুটির একটি চেকবক্সের সাথে করার দরকার ছিল না বরং আরও জটিল পরিস্থিতি যেখানে আমাকে অ্যাডাপ্টারে একটি আলাদা আইটেমটি জানাতে হয়েছিল, তবে আমি একই ধরণের ক্র্যাশ পাচ্ছিলাম। আমি আমার বিজ্ঞপ্তি যুক্তিটি কেবলমাত্র আপডেট করতে আপডেট করেছি যখন ডেটা আসলে পরিবর্তিত হয় এবং এটি আমার ক্র্যাশের সমাধান করে। সুতরাং পুনর্ব্যবহারকারীদের সাথে আমার নতুন নিয়ম: যখন কিছুই পরিবর্তন হয়নি তখন কিছু পরিবর্তন হয়েছে তা অবহিত করবেন না। এই উত্তরের জন্য অনেক ধন্যবাদ!
কোডি এঞ্জেল

2

OnCheckedChangeListener এর পরিবর্তে চেকবক্সে অনিক্লিকলিস্টার ব্যবহার করুন, এটি সমস্যার সমাধান করবে

viewHolder.myCheckBox.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (viewHolder.myCheckBox.isChecked()) {
                // Do something when checkbox is checked
            } else {
                // Do something when checkbox is unchecked                
            }
            notifyDataSetChanged();
        }
    });


1

সাধারণ ব্যবহার পোস্ট:

new Handler().post(new Runnable() {
        @Override
        public void run() {
                mAdapter.notifyItemChanged(mAdapter.getItemCount() - 1);
            }
        }
    });

0

আমি এই সঠিক ইস্যু মধ্যে দৌড়ে! মুনসুর উত্তরটি সত্যই আমার নৌকাকে ভাসিয়ে না দেওয়ার পরে, আমি কিছুটা গণ্ডগোল করেছিলাম এবং এমন একটি সমাধান পেয়েছি যা আমার পক্ষে কাজ করে।

প্রথমত, আমার কোডগুলির কয়েকটি এখানে:

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {

    final Event event = mDataset.get(position);

    //
    //  .......
    //

    holder.mSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            event.setActive(isChecked);
            try {
                notifyItemChanged(position);
            } catch (Exception e) {
                Log.e("onCheckChanged", e.getMessage());
            }
        }
    });

আপনি লক্ষ্য করবেন যে আমি যেমন করছি তার মতো পুরো ডেটাসেটের পরিবর্তে আমি যে অবস্থান পরিবর্তন করছি তার জন্য আমি অ্যাডাপ্টারটি বিশেষত অবহিত করছি। এটি বলা হচ্ছে, যদিও আমি গ্যারান্টি দিতে পারি না এটি আপনার পক্ষে কাজ করবে তবে আমি আমার মোড়ক দিয়ে সমস্যার সমাধান করেছিnotifyItemChanged() কলটি চেষ্টা / ক্যাচ ব্লকে । এটি কেবল ব্যতিক্রম ধরা পড়ে, তবে এখনও আমার অ্যাডাপ্টারটিকে রাষ্ট্র পরিবর্তন পরিবর্তন এবং ডিসপ্লে আপডেট করার অনুমতি দেয়!

আশা করি এটি কাউকে সাহায্য করবে!

সম্পাদনা: আমি স্বীকার করব, এটি সম্ভবত সমস্যাটি হ্যান্ডেল করার সঠিক / পরিপক্ক উপায় নয়, তবে যেহেতু এটি ব্যতিক্রমহীনভাবে রেখে কোনও সমস্যা সৃষ্টি করছে বলে মনে হচ্ছে না, আমি ভেবেছিলাম এটি ভাল হলে আমি ভাগ করে নিই অন্য কারও জন্য যথেষ্ট


0

এটি ঘটছে কারণ আপনি সম্ভবত এই 'সারিটির মানটি কনফিগার করার আগে' শ্রোতা 'সেট করছেন যা শ্রোতাকে চেকবক্সের জন্য' মানটি কনফিগার 'করার সময় ট্রিগার করতে সক্ষম করে।

আপনার যা করা দরকার তা হ'ল:

@Override
public void onBindViewHolder(YourAdapter.ViewHolder viewHolder, int position) {
   viewHolder.mCheckBox.setOnCheckedChangeListener(null);
   viewHolder.mCheckBox.setChecked(trueOrFalse);
   viewHolder.setOnCheckedChangeListener(yourCheckedChangeListener);
}

0
        @Override
        public void onBindViewHolder(final MyViewHolder holder, final int position) {
            holder.textStudentName.setText(getStudentList.get(position).getName());
            holder.rbSelect.setChecked(getStudentList.get(position).isSelected());
            holder.rbSelect.setTag(position); // This line is important.
            holder.rbSelect.setOnClickListener(onStateChangedListener(holder.rbSelect, position));

        }

        @Override
        public int getItemCount() {
            return getStudentList.size();
        }
        private View.OnClickListener onStateChangedListener(final RadioButton checkBox, final int position) {
            return new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (checkBox.isChecked()) {
                        for (int i = 0; i < getStudentList.size(); i++) {

                            getStudentList.get(i).setSelected(false);

                        }
                        getStudentList.get(position).setSelected(checkBox.isChecked());

                        notifyDataSetChanged();
                    } else {

                    }

                }
            };
        }

0

কেবল ব্যবহার isPressed()পদ্ধতি CompoundButtonমধ্যে onCheckedChanged(CompoundButton compoundButton, boolean isChecked)
যেমন

public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {   
                      ... //your functionality    
                            if(compoundButton.isPressed()){
                                notifyDataSetChanged();
                            }
                        }  });

0

চেকবক্স এবং রেডিওবটন ব্যবহার করে আমার একই সমস্যা হয়েছিল। প্রতিস্থাপন করা হচ্ছে notifyDataSetChanged()সঙ্গে notifyItemChanged(position)কাজ করেন। আমি isCheckedডেটা মডেলটিতে একটি বুলিয়ান ক্ষেত্র যুক্ত করেছি । তারপরে আমি বুলিয়ান মানটি আপডেট করেছিলাম এবং কল onCheckedChangedListenerকরেছিলাম notifyItemChanged(adapterPosition)। এটি সেরা উপায় নাও হতে পারে তবে আমার পক্ষে কাজ করেছে। আইটেমটি পরীক্ষা করা হয়েছে কিনা তা যাচাই করার জন্য বুলিয়ান মান ব্যবহার করা হয়।


0

বেশিরভাগ এটা beacause ঘটতে notifydatasetchanged কলিং onCheckedchanged চেকবক্সটি ঘটনা এবং যে ইভেন্টে আবার সেখানে হয় notifydatasetchanged

এটির সমাধানের জন্য আপনি পরীক্ষা করে দেখতে পারেন যে চেকবক্সটি প্রোগ্রামের মাধ্যমে চেক করা হয়েছে বা ব্যবহারকারী এটি চেপেছেন। এর জন্য পদ্ধতিটি চাপানো আছে ।

সুতরাং পুরো তালিকাভুক্ত কোডটি ইস্প্রেড পদ্ধতির অভ্যন্তরে মোড়ানো করুন। এবং এটি সম্পন্ন।

 holder.mBinding.cbAnnual.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

                if(compoundButton.isPressed()) {


                       //your code
                        notifyDataSetChanged();   

            }
        });

0

আমি এই সমস্যাটি ঘন্টার জন্য সহ্য করেছি এবং এটিই আপনি এটি ঠিক করতে পারেন। তবে আপনি শুরু করার আগে এই সমাধানের কিছু শর্ত রয়েছে।

মডেল ক্লাস

public class SelectUserModel {

    private String userName;
    private String UserId;
    private Boolean isSelected;


    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserId() {
        return UserId;
    }

    public void setUserId(String userId) {
        UserId = userId;
    }

    public Boolean getSelected() {
        return isSelected;
    }

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

অ্যাডাপ্টারের ক্লাসে চেকবক্স

CheckBox cb;

অ্যাডাপ্টারের ক্লাস কনস্ট্রাক্টর এবং মডেলের তালিকা

private List<SelectUserModel> userList;

public StudentListAdapter(List<SelectUserModel> userList) {
        this.userList = userList;

        for (int i = 0; i < this.userList.size(); i++) {
            this.userList.get(i).setSelected(false);
        }
    }

ওববিনডভিউ [দয়া করে চেক চেঞ্জের জায়গায় অন্লিক ব্যবহার করুন]

public void onBindViewHolder(@NonNull final StudentListAdapter.ViewHolder holder, int position) {
    holder.cb.setChecked(user.getSelected());
    holder.cb.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            int pos = (int) view.getTag();
            Log.d(TAG, "onClick: " + pos);
            for (int i = 0; i < userList.size(); i++) {
                if (i == pos) {
                    userList.get(i).setSelected(true);
// an interface to listen to callbacks
                    clickListener.onStudentItemClicked(userList.get(i));
                } else {
                    userList.get(i).setSelected(false);
                }
            }
            notifyDataSetChanged();
        }
    });

}


-1

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

সমস্যাটি হ'ল এডিট টেক্সটে কার্সার / ফোকাসটি থেকে যায়।

যখন আমি ব্যবহার করে ফোকাসটি মুছে ফেলেছি:

editText.clearFocus() 

পুনর্ব্যবহারযোগ্য প্রদর্শনের ডেটা পরিবর্তিত পদ্ধতিটি জানিয়ে দিন এই ত্রুটিটি ছুঁড়ে দেওয়া বন্ধ হয়েছে।

আমি মনে করি এটি এই সমস্যার অন্যতম সম্ভাব্য কারণ / সমাধান। এটি সম্পূর্ণ ভিন্ন কারণে এই ব্যতিক্রমটি অন্য কোনওভাবে সংশোধন করা সম্ভব caused

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.