Android: notifyDataSetChanged(); not working

后端 未结 8 1514
旧时难觅i
旧时难觅i 2020-11-28 10:33

I have a database in a server and from a Tablet I take some values from one table in the database. I load this information correctly into a list but I would like to know why

相关标签:
8条回答
  • 2020-11-28 10:58

    As Hissain describes above,

    you need to maintain a reference to the list

    Here's how I got it to work:

    1. Let the list being sent to the adapter be set as an instance member in the activity

    2. In the logic that performs a change to the data, make sure it updates the same list instance that the activity passed to the adapter

    3. Then calling .notifyDataSetChanged(); worked

    Remember that listView position starts at 1, so you will have to do (listViewPosition - 1) for your your java.util.List

    0 讨论(0)
  • 2020-11-28 11:03

    The thing you need to edit is put your

    runOnUiThread(new Runnable() {
                    public void run() {
                        /**
                         * Updating parsed JSON data into ListView
                         * */
                        adapter = new SimpleAdapter(
                                Monitorizacion.this, candidatosList,
                                R.layout.list_item, new String[] { TAG_NSERIE,
                                        TAG_DNI, TAG_NOMBRE, TAG_TEST, TAG_PREGUNTA, TAG_BATERIA},
                                new int[] { R.id.id, R.id.dni, R.id.nombre, R.id.test, R.id.pregunta, R.id.bateria});
                        setListAdapter(adapter);
                        adapter.notifyDataSetChanged();
                    //  timer();
                    }
                });
    

    into the OnCreate(). and return the list candidatosList from Asynctask. than set timer for updating candidatosList list.

    0 讨论(0)
  • 2020-11-28 11:05

    I dont have much reputation to comment on Mr. Hissain answer.It is correct but I want to mention one more thing that reference to the list should not change. If data source underlying is changing, dont change the reference to new list. Actions only need to be done on the same list object. To do the same,clear the list using clear() and then add data to the same list using add() or addALL() and then call notifyDataSetChanged(). eg. On first initialization of the list

    list = dataSource.getList();
    

    then one can add and remove the content from the list and call notifyDataSetChanged() it works fine but if in the code, one tries to change the reference to the other object. Like

    list = dataSource.getList();
    

    where getList() returns the new list everytime, hence the reference changes to some other list object and calling notifyDataSetChnaged does not have impact on the list.But if getList() returns the same list object, it works fine.

    0 讨论(0)
  • 2020-11-28 11:06

    The update function should be called from UI thread. My answer is actually similar to @user1621629's answer with that difference that I am using rxJava, so here's working code that solve this problem for me:

    this.subscriber = myAdapter.getSubscriber(); // keep for unsubscribe in destroy
    dataSource.subscribeOn(Schedulers.computation()).observeOn(AndroidSchedulers.mainThread()).subscribe(this.subscriber);
    

    So I set all execution in order to get data for the list to computation thread, but showing result in UI thread.

    Here's how I create subscriber for this:

    public class MyListAdapter extends RecyclerView.Adapter<LocationListAdapter.ViewHolder> {
    
    
    private List<ListItem> mDataset = new ArrayList<>();
    
    public Subscriber<ListItem[]> getSubscriber() {
        return Subscribers.create(new Action1<ListItem[]>() {
            @Override
            public void call(ListItem[] listItems) {
                mDataset.clear();
                mDataset.addAll(Arrays.asList(listItems));
                notifyDataSetChanged();
            }
        });
    }
    ......
    
    0 讨论(0)
  • 2020-11-28 11:12

    One of the main reasons notifyDataSetChanged() won't work for you - is,

    Your adapter loses reference to your list.

    When you first initialise the Adapter it takes a reference of your arrayList and passes it to its superclass. But if you reinitialise your existing arrayList it losses the reference, and hence, the communication channel with Adapter.

    When creating and adding a new list to the Adapter. Always follow these guidelines:

    1. Initialise the arrayList while declaring it globally.
    2. Add the List to the adapter directly with out checking for null and empty values . Set the adapter to the list directly (don't check for any condition). Adapter guarantees you that wherever you make changes to the data of the arrayList it will take care of it, but never loose the reference.
    3. Always modify the data in the arrayList itself (if your data is completely new than you can call adapter.clear() and arrayList.clear() before actually adding data to the list) but don't set the adapter i.e If the new data is populated in the arrayList than just adapter.notifyDataSetChanged()

    Stay true to the Documentation.

    0 讨论(0)
  • 2020-11-28 11:12

    It might be worth checking if you have an empty override for registerDataSetObserver(). Android Studio added one for me without implementing the call to super. Adding it in as follows was enough to get my listView working again:

    @Override
        public void registerDataSetObserver(DataSetObserver observer) {
            super.registerDataSetObserver(observer);    
        }
    
    0 讨论(0)
提交回复
热议问题