来自非Ui线程的notifyItemRemoved()无法在recyclerview

时间:2017-12-13 09:39:34

标签: android android-recyclerview recycler-adapter

我正在尝试从列表中移除项目并且notifyItemRemoved()方法它不起作用它通过删除最后一项来给出数组索引超出绑定的异常,如果我从中间删除项目,它也会删除下一个项目但是如果把代码放在线程之外它工作正常 有我的代码

       Runnable runnable = new Runnable() {
        @Override
        public void run() {

            int progress = 0;
            ArrayList<MediaFileObject> selection = localDatabase.getAllMediaObjectsOfID(list.get(selectedAlbum).getId());
            for (MediaFileObject obj : selection) {
                if (searializeableTasks.isCancelled())
                    break;
                localDatabase.moveMediaObjectToTrash(obj);
                progress++;
                if (searializeableTasks.isCancelled())
                    sendProgressToHandle(-101);
                else
                    sendProgressToHandle(progress);
            }
            if (!searializeableTasks.isCancelled())
                localDatabase.deleteAlbum(list.get(selectedAlbum).getId());

            Handler handler = new Handler(getMainLooper());
            handler.post(new Runnable() {
                @Override
                public void run() {

                    list.remove(selectedAlbum);
                    savedAlbumAdapter.notifyItemRemoved(selectedAlbum);

                }
            });


        }
    };

    searializeableTasks.startTasks(localDatabase.getAllMediaObjectsOfID(list.get(selectedAlbum).getId()).size(), runnable);

但是如果将所有这些代码放在主线程(Class)中,它的工作正常,我将我的代码放在这里我希望在完成后显示我的自定义进度对话框我想更新我的RecyclerView可以有人请帮我。我的代码有什么问题?或者为什么它不在单独的线程中工作?

3 个答案:

答案 0 :(得分:2)

在主线程上调用通知。

runOnUiThread(new Runnable() {
        @Override
        public void run() {
            savedAlbumAdapter.notifyItemRemoved(selectedAlbum);
        }
    });

 yourrecyclerView.post(new Runnable() {
        @Override
        public void run() {
            savedAlbumAdapter.notifyItemRemoved(selectedAlbum);
        }
    });

答案 1 :(得分:-1)

使用此 - :

而不是

savedAlbumAdapter.notifyItemRemoved(selectedAlbum);

到 - :

notifyDataSetChanged();

答案 2 :(得分:-1)

仅使用

const int square_size = 3;  

int** a = new int*[square_size];
for (int i = 0; i < square_size; i++) {
    a[i] = new int[square_size];
}

std::shared_ptr<int*> sp(a, [](int** a) {for (int i = 0;i < square_size;i++) { delete a[i]; }});

std::ofstream ofs("output.cereal", std::ios::binary);
cereal::BinaryOutputArchive archive(ofs);
archive(sp);

它会工作。如果您在notifyDataSetChanged(); 之后使用notifyItemRemoved(),那么它会再次尝试删除下一个位置,因此remove()会出现。