Android recyclerview 在数据更改后显示更多值

Posted

技术标签:

【中文标题】Android recyclerview 在数据更改后显示更多值【英文标题】:Android recyclerview shows more values after data change 【发布时间】:2021-11-24 06:45:55 【问题描述】:

我正在尝试编辑 recyclerview 中的项目,该项目显示来自 Firebase 的一些数据。但编辑后的数据集并没有改变。它显示以前的以及新的更新项,直到活动重新加载。截图在最后。

我正在通过 alertdialog 编辑项目。以下是代码:

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.MyViewHolder> 
    ArrayList<User_Post> user_posts=null;
Context context;
public ListAdapter(@Nullable ArrayList<User_Post> posts, Context c) 
        this.user_posts=posts;      // the data set
        this.context=c;
    

在项目的编辑按钮上点击AlertDialog打开:

  //'post' is an instance of type User_Post containing the current data item.

dialogBuilder.setPositiveButton("Save", new DialogInterface.OnClickListener() 
    @Override
    public void onClick(DialogInterface dialog, int which) 
        if(isValid()) 
            post.setWorkType(txtType.getSelectedItem().toString());
            post.setWorkDescription(txtDetails.getText().toString());

            user_posts.set(position,post);
            updateDataSet(user_posts);

            saveToFirebase(post,"edit");
            Toast.makeText(context, "Post updated", Toast.LENGTH_SHORT).show();

        
    

firebase 数据更新代码:

private void saveToFirebase(User_Post post, String task) 
    String id=post.getPostID();

    FirebaseDatabase database = FirebaseDatabase.getInstance();
    FirebaseStorage storage = FirebaseStorage.getInstance();
    StorageReference storageRef = storage.getReferenceFromUrl("gs://smart-worker-c73c4.appspot.com/gs:");
    DatabaseReference myRef = database.getReference("posts");

    if(task.equals("edit")) 
        myRef.child(id).setValue(post);
    
    else 
        myRef.child(id).setValue(null);
        storageRef.child(id).delete();
    

用于更新数据集:

private void updateDataSet(ArrayList<User_Post> posts)
    this.user_posts=posts;
    notifyDataSetChanged();

编辑前的截图...

编辑后的截图...

【问题讨论】:

【参考方案1】:

它显示以前的以及新的更新项目,直到重新加载活动

因此,当您重新加载活动时,新数据会显示在RecyclerView 上,因此数据已成功保存到 Firebase,并在重新加载活动时被抓取。所以,这个问题与 firebase 无关。

此外,您决定不对 firebase 使用持久事件侦听器,而是在本地更新了 RecyclerView

 private void updateDataSet(ArrayList<User_Post> posts)
        this.user_posts = posts;
        notifyDataSetChanged();

虽然我建议清除,然后在通知更改之前重建列表:

 private void updateDataSet(ArrayList<User_Post> posts)
        this.user_posts.clear();
        this.user_posts.addAll(posts);        
        notifyDataSetChanged();

这不是最佳过程,因为调用notifyDataSetChanged() 的开销很大;相反,我建议notifyItemInserted() 或notifyItemRangeChanged();仅将更改部署到 RecyclerView

例如,如果您只传递一个项目:

 private void updateDataSet(User_Post post)
        this.user_posts.add(post);        
        notifyItemInserted(this.user_posts.size()-1);

对于一系列项目:

 private void updateDataSet(ArrayList<User_Post> posts) // Pass only those items that are changed
        int currentSize = this.user_posts.size();
        this.user_posts.addAll(posts);   
        int newSize = this.user_posts.size();     
        notifyItemInserted(currentSize, newSize - 1);

【讨论】:

它对我有用。非常感谢@Zain【参考方案2】:

我认为问题在于你给列表的位置可能不是正确的位置,你没有提到你从哪里得到它以及何时更新它。

【讨论】:

以上是关于Android recyclerview 在数据更改后显示更多值的主要内容,如果未能解决你的问题,请参考以下文章

Android的RecyclerView

Android:RecyclerView

RecyclerView

Android之RecyclerView介绍

Android开发Diffutils打造不一样的recyclerview

Android Material Design系列之RecyclerView和CardView