The content of the adapter has changed but ListView did not receive a notification

java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131624175, class android.widget.ListView) with Adapter(class com.invoice.dk.DkfpActivity$a)] at android.widget.ListView.layoutChildren(ListView.java:1576)

 

开发中这个问题出现过很多次,后来自己做了实验,在给Adapter设置数据的时候一般分为以下2种情况

 

1. MyAdapter的数据列表 mInventories是全局变量;代码如下所示,这时可以随意的改变mInventories的指向;

package com.example.davidchen.blogdemo.ui.activity;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.NotificationCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.davidchen.blogdemo.R;
import com.example.davidchen.blogdemo.bean.Inventory;
import com.itheima.nihello.NDKHelper;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * SlideRecyclerView测试
 * <p>
 * Created by SYR on 2019/9/9.
 */

public class SlideRecyclerViewActivity extends AppCompatActivity {

    private ListView recycler_view_list;
    private List<Inventory> mInventories;
    private MyAdapter mInventoryAdapter;
    private ArrayList<Inventory> llll;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recyclerview);

        recycler_view_list = (ListView) findViewById(R.id.recycler_view_list);
        mInventories = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 1; i++) {
            Inventory inventory = new Inventory();
            inventory.setItemDesc("测试数据" + i);
            inventory.setQuantity(random.nextInt(100000));
            inventory.setItemCode("0120816");
            inventory.setDate("20180219");
            inventory.setVolume(random.nextFloat());
            mInventories.add(inventory);
        }
        mInventoryAdapter = new MyAdapter();
        Log.e("TAG", "mInventories=" + mInventories.toString());
        recycler_view_list.setAdapter(mInventoryAdapter);

        findViewById(R.id.add_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (llll == null) {
                    llll = new ArrayList<>();
                }
                llll.clear();
                Random random = new Random();
                Inventory inventory1 = new Inventory();
                inventory1.setItemDesc("Hello" + random.nextInt(1222));
                inventory1.setQuantity(random.nextInt(100000));
                inventory1.setItemCode("0120816");
                inventory1.setDate("20180219");
                inventory1.setVolume(random.nextFloat());
                llll.add(inventory1);

 
                //下面这行给mInventories重新赋值,改变指向,adapter仍然能获取到更新
                mInventories = llll; 
                mInventoryAdapter.notifyDataSetChanged();
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        String result = new NDKHelper().helloFromC();
        Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
    }

    public class MyAdapter extends BaseAdapter {
 
        @Override
        public int getCount() {
            Log.e("MyAdapter", mInventories.toString() + "--------getCount---------");
            return mInventories.size();
        }

        @Override
        public Object getItem(int position) {
            return mInventories.get(position);
        }

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

        ViewHolder holder = null;

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = LayoutInflater.from(SlideRecyclerViewActivity.this).inflate(R.layout.item_inventroy, null);
                holder = new ViewHolder();
                holder.tv_item_desc = (TextView) convertView.findViewById(R.id.tv_item_desc);
                holder.tv_quantity = (TextView) convertView.findViewById(R.id.tv_quantity);
                holder.tv_detail = (TextView) convertView.findViewById(R.id.tv_detail);
                holder.tv_volume = (TextView) convertView.findViewById(R.id.tv_volume);

                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            Inventory bean = mInventories.get(position);
            holder.tv_item_desc.setText(bean.getItemDesc());
            String quantity = bean.getQuantity() + "箱";
            holder.tv_quantity.setText(quantity);
            String detail = bean.getItemCode() + "/" + bean.getDate();
            holder.tv_detail.setText(detail);
            String volume = bean.getVolume() + "方";
            holder.tv_volume.setText(volume);
            return convertView;
        }

        class ViewHolder {
            TextView tv_item_desc, tv_quantity, tv_detail, tv_volume;
        }

    }

}

2. MyAdapter的数据列表 mInventories是局部变量;代码如下所示,这时不可以随意的改变mInventories的指向,改变后适配器也不会刷新;

package com.example.davidchen.blogdemo.ui.activity;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.NotificationCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.davidchen.blogdemo.R;
import com.example.davidchen.blogdemo.bean.Inventory;
import com.itheima.nihello.NDKHelper;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * SlideRecyclerView测试
 * <p>
 * Created by SYR on 2019/9/9.
 */

public class SlideRecyclerViewActivity extends AppCompatActivity {

    private ListView recycler_view_list;
    private List<Inventory> mInventories;
    private MyAdapter mInventoryAdapter;
    private ArrayList<Inventory> llll;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recyclerview);

        recycler_view_list = (ListView) findViewById(R.id.recycler_view_list);
        mInventories = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 1; i++) {
            Inventory inventory = new Inventory();
            inventory.setItemDesc("测试数据" + i);
            inventory.setQuantity(random.nextInt(100000));
            inventory.setItemCode("0120816");
            inventory.setDate("20180219");
            inventory.setVolume(random.nextFloat());
            mInventories.add(inventory);
        }
        mInventoryAdapter = new MyAdapter(mInventories);
        Log.e("TAG", "mInventories=" + mInventories.toString());
        recycler_view_list.setAdapter(mInventoryAdapter);

        findViewById(R.id.add_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (llll == null) {
                    llll = new ArrayList<>();
                }
                llll.clear();
                Random random = new Random();
                Inventory inventory1 = new Inventory();
                inventory1.setItemDesc("Hello" + random.nextInt(1222));
                inventory1.setQuantity(random.nextInt(100000));
                inventory1.setItemCode("0120816");
                inventory1.setDate("20180219");
                inventory1.setVolume(random.nextFloat());
                llll.add(inventory1);

                //下面这行给mInventories重新赋值,改变指向,adapter不能获取到更新,因为 
                //adapter绑定的数据的仍然是原来的mInventories的地址
                mInventories = llll;
                mInventoryAdapter.notifyDataSetChanged();
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        String result = new NDKHelper().helloFromC();
        Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
    }

    public class MyAdapter extends BaseAdapter {

        List<Inventory> mInventories;

        MyAdapter(List<Inventory> list){
            mInventories = list;
        }

        @Override
        public int getCount() {
            Log.e("MyAdapter", mInventories.toString() + "--------getCount---------");
            return mInventories.size();
        }

        @Override
        public Object getItem(int position) {
            return mInventories.get(position);
        }

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

        ViewHolder holder = null;

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = LayoutInflater.from(SlideRecyclerViewActivity.this).inflate(R.layout.item_inventroy, null);
                holder = new ViewHolder();
                holder.tv_item_desc = (TextView) convertView.findViewById(R.id.tv_item_desc);
                holder.tv_quantity = (TextView) convertView.findViewById(R.id.tv_quantity);
                holder.tv_detail = (TextView) convertView.findViewById(R.id.tv_detail);
                holder.tv_volume = (TextView) convertView.findViewById(R.id.tv_volume);

                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            Inventory bean = mInventories.get(position);
            holder.tv_item_desc.setText(bean.getItemDesc());
            String quantity = bean.getQuantity() + "箱";
            holder.tv_quantity.setText(quantity);
            String detail = bean.getItemCode() + "/" + bean.getDate();
            holder.tv_detail.setText(detail);
            String volume = bean.getVolume() + "方";
            holder.tv_volume.setText(volume);
            return convertView;
        }

        class ViewHolder {
            TextView tv_item_desc, tv_quantity, tv_detail, tv_volume;
        }

    }

}

需要注意的是数据的改变如data.clear() 和 adapter的刷新notifyDataSetChanged不要间隔好久,不然如果这个间隔内,adapter内容重新绘制的话,容易出现如题目的报错;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值