有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何更新RecyclerView的数据集并从视图持有者处通知适配器?

我有一个使用RecyclerView构建的帖子列表。我在这个场景中使用的类是片段、适配器和视图持有者。加载片段时,我使用okhttp从API调用中获取帖子列表,并将列表传递给适配器

对于列表中的每个项目,我都有一个上下文菜单,我正在视图持有者中定义它,如下所示

@Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        menu.setHeaderTitle("Actions");

        if (!post.isRemoved()) {
            menu.add(Menu.NONE, 1, 1, "Move to Trash")
                    .setOnMenuItemClickListener(onTrashMenu);
        }
        else {
            menu.add(Menu.NONE, 1, 1, "Delete")
                    .setOnMenuItemClickListener(onDeleteMenu);

            menu.add(Menu.NONE, 2, 2, "Restore")
                    .setOnMenuItemClickListener(onRestoreMenu);
        }
    }

此外,每个侦听器都在视图持有者类中。例如:

private final MenuItem.OnMenuItemClickListener onDeleteMenu = item -> {
        OkHttpClient client = new OkHttpClient();
        String url = "SOME_URL";

        Request request = new Request.Builder()
                .url(url)
                .delete()
                .header("SOME_HEADER")
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                Log.e("POSTS_VIEW_HOLDER", e.getMessage());
                Snackbar.make(PostViewHolder.super.itemView, "Failed to remove post.", Snackbar.LENGTH_SHORT)
                        .show();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                Snackbar.make(PostViewHolder.super.itemView, "Post removed.", Snackbar.LENGTH_SHORT)
                        .show();
            }
        });

        return true;
    };

我尝试过用here描述的方式使用接口

适配器的构造函数需要接口作为参数。然后在创建视图时将其进一步传递给视图持有者

public PostsAdapter(Post[] posts, AdapterInterface adapterInterface) {
        this.posts = posts;
        this.adapterInterface = adapterInterface;
    }

@NonNull
    @Override
    public PostViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View postItemView = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.post_item, viewGroup, false);

        return new PostViewHolder(postItemView, adapterInterface);
    }

从片段中传递,如下所示:

postsAdapter = new PostsAdapter(null, this::loadPosts);

loadPosts()方法使用okhttp,并在回调中设置适配器的数据集和调用。notifyDataSetChanged()

从视图持有者中的接口调用该方法时,我得到了以下结果:

only the original thread that created a view hierarchy can touch its views

所以我用了一个处理器来绕过它:

private Handler mHandler = new Handler(Looper.getMainLooper());

mHandler.post(() -> {
                    adapterInterface.dataSetChanged();
                });

但是现在,无论何时调用此方法,都不会发生任何事情。我想知道我所做的是否有意义,还有,是否有更好的方法(或者至少是一种有效的方法)来实现这一点

编辑

loadPosts()实现:

public void loadPosts() {
        progressBar.setVisibility(View.VISIBLE);
            Request request = new Request.Builder()
                    .url(url)
                    .build();

        this.client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    Log.e(tag, e.getMessage());
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    final Post[] posts = gson.fromJson(response.body().string(), Post[].class);

                    mHandler.post(() -> {
                        postsAdapter.setPosts(posts);
                        postsAdapter.notifyDataSetChanged();
                        progressBar.setVisibility(View.INVISIBLE);
                    });
                }
        });
    }

共 (0) 个答案