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) 个答案