Я пытаюсь удалить свой элемент из recyclerview, но я всегда получаю ошибку
java.lang.IllegalStateException: не удается вызвать этот метод, в то время как RecyclerView вычисляет макет или прокрутку
Я использую notify datasetchanged, могу ли я решить это?
public class AdapterIntransit extends RecyclerView.Adapter<AdapterIntransit.ViewHolder> {
private Context context;
List<DataIntransit> data;
public AdapterIntransit(Context context, List<DataIntransit> data) {
this.context = context;
this.data = data;
}
@Override
public AdapterIntransit.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardintransit, parent, false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(AdapterIntransit.ViewHolder holder, int position) {
if (data.get(position).getJml1() - data.get(position).getJml2() <= 0) {
data.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, getItemCount());
notifyDataSetChanged();
} else {
holder.kode.setText(data.get(position).getKode());
holder.nama.setText(data.get(position).getNama());
holder.jumlah.setText(String.valueOf(data.get(position).getJml1() - data.get(position).getJml2()));
}
}
@Override
public int getItemCount() {
return data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView kode, nama, jumlah;
public ViewHolder(View itemView) {
super(itemView);
kode = (TextView)itemView.findViewById(R.id.kode);
nama = (TextView)itemView.findViewById(R.id.nama);
jumlah = (TextView)itemView.findViewById(R.id.jumlah);
}
}
}
Ответ 1
Ниже ответ работал для меня
dialeecyclerView.post(new Runnable()
{
@Override
public void run() {
myadapter.notifyDataSetChanged();
}
});
Вы используете свой экземпляр RecyclerView
а внутри метода post новый Runnable добавляется в очередь сообщений. Runnable будет запущен в потоке пользовательского интерфейса. Это ограничение для Android для доступа к потоку UI
из фона (например, внутри метода, который будет выполняться в фоновом потоке). для большего вы запускаете его в потоке UI
если вам нужно.
Для большего вы можете запустить его в потоке UI
, если вам нужно
runOnUiThread(new Runnable(){
public void run() {
// UI code goes here
}
});
Ответ 2
Это полезно, когда установлен флажок "Все" при щелчке по верхнему флажку в представлении реселлера.
recyclerview.post(new Runnable()
{
@Override
public void run() {
myadapter.notifyDataSetChanged();
}
});
Ответ 3
Я даю вам еще одну идею для решения вашей проблемы. Я думаю, что это может быть лучше. Идея в том, что мы не удаляем недействительные данные внутри onBindViewHolder
, мы удалим их раньше
public AdapterIntransit(Context context, List < DataIntransit > data) {
this.context = context;
this.data = removeInValidData(data);
}
private void removeInValidData(List < DataIntransit > data) {
for (int position = 0, position < data.size(); position++) {
if (data.get(position).getJml1() - data.get(position).getJml2() <= 0) {
data.remove(position);
}
}
}
@Override
public void onBindViewHolder(AdapterIntransit.ViewHolder holder, int position) {
holder.kode.setText(data.get(position).getKode());
holder.nama.setText(data.get(position).getNama());
holder.jumlah.setText(String.valueOf(data.get(position).getJml1() - data.get(position).getJml2()));
}
Ответ 4
Вы уведомляете об изменении элемента внутри onBindViewHolder()
, когда ваш элемент находится в процессе конструирования. Скорее всего, вы можете просто улучшить свою логику, чтобы избежать этого.
Ответ 5
Не стоит писать эти логики в методе вашего адаптера onBindViewHolder()
.
Но если вам это действительно нужно, вы можете сделать что-то вроде этого:
new Handler().post(new Runnable() {
@Override
public void run() {
// your code here. eg: notifyDataSetChanged()
}
});