Android RecyclerView: InformDataSetChanged () IllegalStateException


130

मैं InformDataSetChanged () का उपयोग करके एक रीसायकल के आइटम को अपडेट करने की कोशिश कर रहा हूं।

यह रीसायकलव्यू एडॉप्टर में मेरा onBindViewHolder () तरीका है।

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

मैं भी InformItemChanged (), एक ही अपवाद का इस्तेमाल किया। एडॉप्टर को सूचित करने के लिए अपडेट करने का कोई गुप्त तरीका जो कुछ बदला है?


im अब एक ही मुद्दा रहा है। देखने वाले कंस्ट्रक्टर में सेटनचेक किए गए श्रोता को मुझे एक ही त्रुटि दें
गंदी_छवि

जवाबों:


145

आपको विधि 'setOnCheckedChangeListener ()' को ViewHolder पर ले जाना चाहिए जो आपके एडॉप्टर पर इनर क्लास है।

onBindViewHolder()एक ऐसी विधि नहीं है जो प्रारंभिक हो ViewHolder। यह विधि प्रत्येक पुनर्नवीनीकरण आइटम को ताज़ा करने का चरण है। जब आप कॉल करते हैं notifyDataSetChanged(), onBindViewHolder()तो प्रत्येक आइटम समय की संख्या के रूप में कहा जाएगा।

इसलिए यदि आप चेकबॉक्स में notifyDataSetChanged()डालते हैं onCheckChanged()और चेकबॉक्स को इनिशियलाइज़ करते हैं onBindViewHolder(), तो आपको परिपत्र पद्धति कॉल के कारण IllegalStateException मिल जाएगी।

checkbox पर क्लिक करें -> onCheckedChanged () -> InformDataSetChanged () -> 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 पसंद करते हैं । इसने मुझे RecyclerView में "RadioGroup" बनाने की भी अनुमति दी।
आर्टेम

मुझे अपनी सूची में आइटम पोस्ट कैसे मिलेगा ??
गंदी_विलास

2
यह देखने वाले में मेरे लिए काम नहीं करता है। अभी भी क्रैश त्रुटि मिलती है। मैं सरणी में vars बदलने की जरूरत है। बहुत अजीब। यह भी सुनिश्चित नहीं है कि मैं कहाँ से लिंटर अटैच कर सकता हूँ।
गंदी_विलास

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
अच्छा जवाब है, लेकिन प्रत्येक onBindViewHolder कॉल पर श्रोता नहीं बनाना बेहतर है। इसे एक क्षेत्र के रूप में बनाएं।
आर्टेम

1
एक क्षेत्र का उपयोग करना बेहतर है, मैं सिर्फ एक उदाहरण दे रहा हूं जो काम करता है। लेकिन चेतावनी के लिए धन्यवाद, मैं जवाब को अपडेट करूंगा।
जोनीडीएस J

1
मुझे वास्तव में हर बार किसी भी नए श्रोता को बांधने की आवश्यकता है, क्योंकि श्रोता को हर बार एक अद्यतन स्थिति चर की आवश्यकता होती है। तो यह एक शानदार जवाब है इसलिए मुझे हैंडलर का उपयोग नहीं करना है।
रॉक ली

यह निश्चित रूप से इसे करने का सबसे अच्छा तरीका है क्योंकि इसे वैश्विक स्थिति रखने के लिए कभी भी अनुशंसित नहीं किया जाता है, जिसे स्वीकृत उत्तर ( stackoverflow.com/a/31069171/882251 ) अनुशंसित कर रहा है।
डारविंड

सबसे सरल एक !! धन्यवाद !!
दलवीरसिंहदैया

39

एक का उपयोग करते हुए Handlerआइटम जोड़ने और फोन करने के लिए notify...()इस से Handlerमेरे लिए समस्या का समाधान हो।


3
यह सही उत्तर है, आप सेटिंग करते समय (onBindViewHolder को कॉल करने के साथ) आइटम नहीं बदल सकते। उस स्थिति में आपको हैंडलर.पोस्ट ()
pjanecze

1
@ user1232726 यदि आप मुख्य थ्रेड पर हैंडलर बनाते हैं, तो आपको लूपर (कॉलिंग लूपर को चूक) निर्दिष्ट करने की आवश्यकता नहीं है। तो हाँ, यह मेरी सलाह है। अन्यथा आप लॉपर को मैन्युअल रूप से भी निर्दिष्ट कर सकते हैं।
साइबरजेन

दुर्भाग्य से मेरे चेकबॉक्स की जाँच नहीं की जाती है जब मैं नीचे स्क्रॉल करता हूं और फिर से वापस स्क्रॉल करता हूं। बू। lol
filthy_wizard

@ user1232726 उत्तर की खोज करें या अपने मुद्दे का वर्णन करते हुए एक नया प्रश्न पूछें।
सायबरजेन

2
मैं दृढ़ता से इस उत्तर को हतोत्साहित करूंगा क्योंकि यह समस्या को हल करने का एक आसान तरीका है। अधिक आप ऐसा करते हैं कि आपका कोड समझने के लिए जटिल हो जाता है। समस्या को समझने के लिए मूनसो के जवाब को देखें और समस्या को हल करने के लिए जोनीडीएस का जवाब दें।
कल्पेश पटेल

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
अच्छा काम) परन्तु केवल क्लिक पर (अगर मैं धीमी चाल विजेट (SwitchCompat), इस कार्रवाई missed.This हो जाएगा केवल मुद्दा है
Vlad

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फिर से कॉल करता है । आप कॉल नहीं कर सकते हैं onBindViewHolderजब आप में पहले से ही कर रहे हैं onBindViewHolder], क्योंकि आप नहीं कर सकते हैं notifyItemRangeChangedअगर आप पहले से सूचित किया जाएगा कि आइटम रेंज बदल गया है के बीच में हैं। लेकिन मुझे केवल इसे चालू या बंद दिखाने के लिए यूआई को अपडेट करने की आवश्यकता थी, वास्तव में कुछ भी ट्रिगर नहीं करना चाहता था।

यहाँ वह समाधान है जो मैंने JoniDS के उत्तर से सीखा है जो अनंत लूप को रोक देगा। जब तक हम चेकर को सेट करने से पहले श्रोता को "अशक्त" करते हैं, तब तक यह अनन्त लूप से बचते हुए, श्रोता को ट्रिगर किए बिना UI को अपडेट कर देगा। फिर हम श्रोता को बाद में सेट कर सकते हैं।

जोनीडीएस कोड:

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

आपको OnBindViewHolder में OnCheckedChangeListener को बार-बार शुरू करने से बचना चाहिए (कम GC को इस तरह की आवश्यकता है)। यह onCreateViewHolder में कहा जाता है, और आप धारक को कॉल करके स्थिति प्राप्त करते हैं। AdapterPosition ()।
Android डेवलपर

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कि कॉलबैक को ट्रिगर कर रहा है तो मामला होगा) के बराबर नहीं होने पर आप इसे सूचित नहीं कर सकते हैं ।


धन्यवाद @ प्रियजीत! मेरा मुद्दा एक चेकबॉक्स के साथ नहीं था, लेकिन अधिक जटिल स्थिति में जहां मुझे एडॉप्टर में एक अलग आइटम को सूचित करना था, लेकिन मुझे एक समान दुर्घटना हो रही थी। मैंने अपने नोटिफिकेशन लॉजिक को केवल अपडेट करने के लिए अपडेट किया जब डेटा वास्तव में बदल रहा है और इसने मेरे क्रैश को हल किया। तो RecyclerViews के साथ मेरा नया नियम: यह मत अधिसूचित करें कि जब कुछ भी नहीं बदला तो कुछ बदल गया। इस उत्तर के लिए बहुत धन्यवाद!
कोडीजेल

2

OnCheckedChangeListener के बजाय चेकबॉक्स पर onClickListner का उपयोग करें, यह समस्या को हल करेगा

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

ONBINDVIEW [ onCheckChange की जगह onclick का उपयोग करें]

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 से Done, Back, या बाहर के इनपुट टच से बाहर निकला। यह इनपुट टेक्स्ट के साथ मॉडल को अपडेट करने का कारण बनता है, फिर लाइव डेटा अवलोकन के माध्यम से पुनर्नवीनीकरण दृश्य को ताज़ा करें।

समस्या यह थी कि EditText में कर्सर / फ़ोकस बना रहता है।

जब मैंने उपयोग करके फोकस हटा दिया है:

editText.clearFocus() 

रीसाइक्लर व्यू के डेटा बदले हुए तरीके को सूचित करें इस त्रुटि को फेंकना बंद करें।

मुझे लगता है कि यह इस समस्या का संभावित कारण / समाधान है। यह संभव है कि यह अपवाद दूसरे तरीके से तय किया जा सकता है क्योंकि यह पूरी तरह से अलग कारण से हो सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.