Trình tái chế Android: notifyDataSetChanged () IllegalStateException


130

Tôi đang cố gắng cập nhật các mục của một bản tái chế bằng cách sử dụng notifyDataSetChanged ().

Đây là phương thức onBindViewHolder () của tôi trong bộ điều hợp tái chế.

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

Những gì tôi muốn làm là cập nhật các mục danh sách, sau khi tôi chọn một hộp kiểm. Tôi nhận được một ngoại lệ bất hợp pháp mặc dù:"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)

Tôi cũng đã sử dụng notifyItemChanged (), ngoại lệ tương tự. Bất kỳ cách bí mật để cập nhật để thông báo cho bộ chuyển đổi rằng một cái gì đó thay đổi?


Tôi có vấn đề tương tự bây giờ. đặt trình lắng nghe setoncheckchanged vào hàm tạo của khung nhìn cho tôi cùng một lỗi
filthy_wizard

Câu trả lời:


145

Bạn nên di chuyển phương thức 'setOnCheckedChangeListener ()' sang ViewHolder, lớp bên trong bộ điều hợp của bạn.

onBindViewHolder()không phải là một phương thức khởi tạo ViewHolder. Phương pháp này là bước làm mới mỗi mục tái chế. Khi bạn gọi notifyDataSetChanged(), onBindViewHolder()sẽ được gọi là số lần của mỗi mục.

Vì vậy, nếu bạn notifyDataSetChanged()đưa vào onCheckChanged()và khởi tạo checkBox onBindViewHolder(), bạn sẽ nhận được IllegalStateException vì cuộc gọi phương thức vòng tròn.

nhấp vào hộp kiểm -> onCheckedChanged () -> notifyDataSetChanged () -> onBindViewHolder () -> đặt hộp kiểm -> onChecked ...

Đơn giản, bạn có thể khắc phục điều này bằng cách đặt một cờ vào Adaptor.

thử cái này,

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

Tôi thấy, có ý nghĩa. Mong muốn nền tảng sẽ dự đoán hành vi đơn giản như vậy và đưa ra giải pháp thay vì phải dựa vào cờ ..
Arthur

Không quan trọng bạn đặt người nghe ở đâu miễn là bạn không thông báo AdapterViewObservertrong khi onBindViewHolder()tiến hành.
Yaroslav Mytkalyk

6
Tôi thích giải pháp này stackoverflow.com/a/32373999/1771194 với một số cải tiến trong nhận xét. Nó cũng cho phép tôi tạo "Radiogroup" trong RecyclerView.
Artem

Làm thế nào để tôi có được các mục postion trong danh sách của tôi ??
filthy_wizard

2
Điều này không làm việc cho tôi trong khung nhìn. vẫn nhận được lỗi sự cố. tôi cần thay đổi vars trong danh sách mảng. rất lạ. không quá chắc chắn nơi tôi có thể đính kèm listiner.
filthy_wizard ngày

45

Bạn chỉ có thể đặt lại trình nghe trước đó trước khi thực hiện thay đổi và bạn sẽ không gặp ngoại lệ này.

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
Câu trả lời tốt, nhưng tốt hơn là không tạo người nghe trên mỗi cuộc gọi onBindViewHolder. Làm cho nó như là một lĩnh vực.
Artem

1
Sử dụng một lĩnh vực tất nhiên là tốt hơn, tôi chỉ đưa ra một ví dụ hoạt động. Nhưng cảm ơn vì cảnh báo, tôi sẽ cập nhật câu trả lời.
JoniDS

1
Tôi thực sự cần phải ràng buộc một người nghe mới mỗi lần, bởi vì người nghe cần một biến vị trí được cập nhật mỗi lần. Vì vậy, đây là một câu trả lời tuyệt vời để tôi không phải sử dụng Handler.
Rock Lee

Đây chắc chắn là cách tốt nhất để làm điều đó vì không bao giờ nên giữ trạng thái toàn cầu, mà câu trả lời được chấp nhận ( stackoverflow.com/a/31069171/882251 ) được khuyến nghị.
Darwind

Đơn giản nhất !! Cảm ơn !!
DalveerSinghDaiya

39

Việc sử dụng Handlerđể thêm các mục và gọi notify...()từ điều này đã Handlerkhắc phục sự cố cho tôi.


3
Đó là câu trả lời đúng, bạn không thể thay đổi mục trong khi cài đặt (bằng cách gọi onBindViewHolder). Trong trường hợp đó, bạn phải gọi notifyDataSetChanged ở cuối vòng lặp hiện tại bằng cách gọi Handler.post ()
pjanecze

1
@ user1232726 Nếu bạn tạo Trình xử lý trên luồng chính, bạn không phải chỉ định Looper (mặc định cho trình xử lý cuộc gọi looper). Vì vậy, có, đây là lời khuyên của tôi. Nếu không, bạn cũng có thể chỉ định Looper bằng tay.
cybergen 3/03/2016

Thật không may, các hộp kiểm của tôi không được kiểm tra khi tôi cuộn xuống và cuộn lại. boo. lol
filthy_wizard

@ user1232726 tìm kiếm câu trả lời hoặc đặt câu hỏi mới mô tả vấn đề của bạn.
cybergen 3/03/2016

2
Tôi sẽ không khuyến khích mạnh mẽ câu trả lời này vì đây là một cách khó khăn để giải quyết vấn đề. Nhiều bạn làm điều này nhiều hơn mã của bạn trở nên phức tạp để hiểu. Tham khảo câu trả lời của Moonsoo để hiểu vấn đề và câu trả lời của JoniDS để giải quyết vấn đề.
Kalpesh Patel

26

Tôi không biết rõ, nhưng tôi cũng gặp vấn đề tương tự. Tôi đã giải quyết điều này bằng cách sử dụng onClickListnertrêncheckbox

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

Hãy thử điều này, điều này có thể giúp!


1
Công việc tuyệt vời) NHƯNG chỉ khi nhấp chuột (nếu tôi di chuyển chậm widget (SwitchCompat), hành động này sẽ bị bỏ qua. Đây là vấn đề duy nhất
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);
                }
            }
        });
    }

Tôi cho rằng bạn có thể dễ dàng thông báo bộ điều hợp hai lần.
Максим Петллк

8

Khi bạn gặp lỗi Tin nhắn:

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

Đơn giản, chỉ cần làm những gì gây ra Ngoại lệ trong:

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

1
Điều này làm việc cho tôi. Tự hỏi có bất kỳ vấn đề với giải pháp này?
Sayooj Valsan

7

Tìm thấy một giải pháp đơn giản -

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

Ở đây chúng tôi tạo một runnable để thông báoItemChanged cho một vị trí khi recyclerview sẵn sàng để xử lý nó.


5

mục CheckBox của bạn đang thay đổi có thể rút được khi bạn gọi notifyDataSetChanged();để xảy ra ngoại lệ này. Hãy thử gọi notifyDataSetChanged();trong bài của quan điểm của bạn. Ví dụ:

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

4

Lúc đầu, tôi nghĩ câu trả lời của Moonsoo ( câu trả lời được chấp nhận) sẽ không hiệu quả với tôi vì tôi không thể khởi tạosetOnCheckedChangeListener() trình xây dựng của ViewHolder vì tôi cần liên kết nó mỗi lần để nó có được một biến vị trí được cập nhật. Nhưng tôi phải mất một thời gian dài để nhận ra những gì anh ấy đang nói.

Dưới đây là một ví dụ về "cuộc gọi phương thức vòng tròn" mà anh ta đang nói đến:

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

Vấn đề duy nhất với điều này là khi chúng ta cần khởi tạo công tắc bật hoặc tắt (ví dụ từ trạng thái đã lưu trong quá khứ), nó đang gọi người nghe có thể gọi lại cuộc gọi nofityItemRangeChangednào onBindViewHolder. Bạn không thể gọi onBindViewHolderkhi bạn đã ở onBindViewHolder], bởi vì bạn không thể notifyItemRangeChangednếu bạn đang ở giữa thông báo rằng phạm vi mục đã thay đổi.Nhưng tôi chỉ cần cập nhật giao diện người dùng để hiển thị hoặc tắt nó, không muốn thực sự kích hoạt bất cứ điều gì.

Đây là giải pháp tôi học được từ câu trả lời của JoniDS sẽ ngăn chặn vòng lặp vô hạn. Miễn là chúng ta đặt trình nghe thành "null" trước khi chúng ta đặt Đã kiểm tra, thì nó sẽ cập nhật giao diện người dùng mà không kích hoạt trình nghe, tránh vòng lặp vô hạn. Sau đó chúng ta có thể thiết lập người nghe sau.

Mã của JoniDS:

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

Giải pháp đầy đủ cho ví dụ của tôi:

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

Bạn nên tránh khởi tạo lại OnCheckedChangeListener trong onBindViewHolder (cần ít GC hơn theo cách này). Điều này được cho là được gọi trong onCreateViewHolder và bạn có được vị trí bằng cách gọi chủ sở hữu.getAd ModuleP vị trí ().
nhà phát triển Android

4

Tại sao không kiểm tra RecyclerView.isComputingLayout()trạng thái như sau?

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

Mặc dù mục bị ràng buộc bởi trình quản lý bố cục, rất có khả năng bạn đang đặt trạng thái đã chọn của hộp kiểm của mình, điều này đang kích hoạt cuộc gọi lại.

Tất nhiên đây là một phỏng đoán vì bạn đã không xuất bản theo dõi ngăn xếp đầy đủ.

Bạn không thể thay đổi nội dung bộ điều hợp trong khi RV đang tính toán lại bố cục. Bạn có thể tránh điều đó bằng cách không gọi notifyDataSetChanged nếu trạng thái đã kiểm tra của mục bằng với giá trị được gửi trong cuộc gọi lại (sẽ là trường hợp nếu cuộc gọi checkbox.setCheckedđang kích hoạt cuộc gọi lại).


Cảm ơn @yigit! Vấn đề của tôi không liên quan đến hộp kiểm nhưng tình huống phức tạp hơn khi tôi phải thông báo cho một mục khác trong bộ điều hợp, nhưng tôi đã gặp sự cố tương tự. Tôi đã cập nhật logic thông báo của mình để chỉ cập nhật khi dữ liệu thực sự thay đổi và nó đã giải quyết sự cố của tôi. Vì vậy, quy tắc mới của tôi với RecyclerViews: không thông báo rằng có gì đó đã thay đổi khi không có gì thay đổi. Rất cám ơn cho câu trả lời này!
CodyEngel

2

Sử dụng hộp kiểm onClickListner thay vì OnCheckedChangeListener, Nó sẽ giải quyết vấn đề

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

Trước khi notifyDataSetChanged()chỉ cần kiểm tra với phương pháp này:recyclerView.IsComputingLayout()


1

Sử dụng đơn giản Bài:

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

0

Tôi gặp vấn đề chính xác này! Sau khi câu trả lời của Moonsoo không thực sự nổi thuyền của tôi, tôi đã loay hoay một chút và tìm ra giải pháp hiệu quả cho mình.

Đầu tiên, đây là một số mã của tôi:

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

Bạn sẽ nhận thấy tôi đặc biệt thông báo bộ điều hợp cho vị trí tôi đang thay đổi, thay vì toàn bộ tập dữ liệu như bạn đang làm. Điều đó đang được nói, mặc dù tôi không thể đảm bảo điều này sẽ hiệu quả với bạn, tôi đã giải quyết vấn đề bằng cách gói notifyItemChanged()cuộc gọi của mình vào một khối thử / bắt. Điều này chỉ đơn giản là bắt ngoại lệ, nhưng vẫn cho phép bộ điều hợp của tôi đăng ký thay đổi trạng thái và cập nhật màn hình!

Hy vọng điều này sẽ giúp được ai đó!

EDIT: Tôi sẽ thừa nhận, đây có lẽ không phải là cách xử lý vấn đề đúng đắn / chín chắn, nhưng vì nó dường như không gây ra bất kỳ vấn đề nào bằng cách giải quyết ngoại lệ, tôi nghĩ tôi sẽ chia sẻ trong trường hợp nó tốt đủ cho người khác


0

Điều này xảy ra bởi vì có lẽ bạn đang đặt 'trình nghe' trước khi bạn định cấu hình giá trị cho hàng đó, điều này làm cho trình nghe được kích hoạt khi bạn 'định cấu hình giá trị' cho hộp kiểm.

Những gì bạn cần làm là:

@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

chỉ cần sử dụng isPressed()phương thức CompoundButtontrong onCheckedChanged(CompoundButton compoundButton, boolean isChecked)
ví dụ

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

0

Tôi gặp vấn đề tương tự khi sử dụng Hộp kiểm và RadioButton. Thay thế notifyDataSetChanged()bằng notifyItemChanged(position)làm việc. Tôi đã thêm một trường Boolean isCheckedvào mô hình dữ liệu. Sau đó, tôi cập nhật giá trị Boolean và trong onCheckedChangedListener, tôi đã gọi notifyItemChanged(adapterPosition). Đây có thể không phải là cách tốt nhất, nhưng làm việc cho tôi. Giá trị boolean được sử dụng để kiểm tra xem mục có được kiểm tra hay không.


0

chủ yếu là nó xảy ra + Nhà notifydatasetchanged gọi onCheckedchanged trường hợp hộp kiểm và trong đó sự kiện một lần nữa có được notifydatasetchanged .

để giải quyết nó, bạn chỉ cần kiểm tra xem hộp kiểm được kiểm tra bằng cách lập trình hoặc người dùng nhấn nó. Có phương pháp isPress cho nó.

Vì vậy, bọc toàn bộ mã listner bên trong phương thức isPress. và nó được thực hiện.

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

                if(compoundButton.isPressed()) {


                       //your code
                        notifyDataSetChanged();   

            }
        });

0

Tôi đã chịu đựng vấn đề này hàng giờ và đây là cách bạn có thể khắc phục nó. Nhưng trước khi bạn bắt đầu có một số điều kiện cho giải pháp này.

LỚP MODEL

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

KIỂM TRA trong lớp ADAPTER

CheckBox cb;

QUẢNG CÁO XÂY DỰNG LỚP & DANH SÁCH MÔ HÌNH

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 [Vui lòng sử dụng onclick thay cho onCheckChange]

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

Đối với tôi, sự cố xảy ra khi tôi thoát khỏi EditText bằng Xong, Quay lại hoặc chạm bên ngoài. Điều này gây ra cập nhật mô hình với văn bản đầu vào, sau đó làm mới chế độ xem tái chế thông qua quan sát dữ liệu trực tiếp.

Vấn đề là con trỏ / tiêu điểm vẫn còn trong EditText.

Khi tôi đã xóa tiêu điểm bằng cách sử dụng:

editText.clearFocus() 

Thông báo thay đổi dữ liệu phương pháp của chế độ xem tái chế đã ngừng ném lỗi này.

Tôi nghĩ rằng đây là một trong những lý do / giải pháp có thể cho vấn đề này. Có thể là ngoại lệ này có thể được sửa chữa theo một cách khác vì nó có thể được gây ra bởi lý do hoàn toàn khác nhau.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.