List<User> 不删除它包含在 RecyclerView 适配器中的 POJO 对象

Posted

技术标签:

【中文标题】List<User> 不删除它包含在 RecyclerView 适配器中的 POJO 对象【英文标题】:List<User> not Removing POJO Object it Contains in RecyclerView Adapter 【发布时间】:2019-03-20 00:48:04 【问题描述】:

我正在从 Firebase 数据库中读取用户(姓名、年龄)的数据并将其显示在回收站视图中。当用户长按某个项目时,该项目已成功从 firebase 中删除,但是当我尝试在子侦听器的 onChildRemoved 方法中从 List of users 中删除该项目时,例如 List ,用户不会被删除。代码是:

mChildListener=new ChildEventListener() 
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) 

                User user=dataSnapshot.getValue(User.class);
                user.setUid(dataSnapshot.getKey());

                mDataList.add(user);
                mUserAdapter.notifyDataSetChanged();
                //passing the user returned to adapter but didn't work
                mUserAdapter.updateDataSet(user);
            
            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot)   
                User user=dataSnapshot.getValue(User.class);
                user.setUid(dataSnapshot.getKey());

                mDataList.remove(user);
                mUserAdapter.notifyDataSetChanged();
            
        ;

这是用户模型类:

public class User 
    private String uid;
    private String name;
    private int age;
    public User() 
    public User(String uid, String name, int age) 
        this.uid = uid;
        this.name = name;
        this.age = age;
    
    public User(String name, int age) 
        this.name = name;
        this.age = age;
    
    public String getUid() return uid;
    public void setUid(String uid) this.uid = uid;
    public String getName() return name;
    public void setName(String name) this.name = name;
    public int getAge() return age;
    public void setAge(int age) this.age = age;

回收站视图代码是这样的:

@Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) 

        User user=mDataList.get(position);

        holder.textView.setText(user.getName()+ "  |  "+user.getAge());

        holder.textView.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                String uid=user.getUid();
                Intent intent=new Intent(mContext,DetailsActivity.class);
                intent.putExtra(USER_KEY,uid);
                mContext.startActivity(intent);
            
        );
        holder.textView.setOnLongClickListener(new View.OnLongClickListener() 
            @Override
            public boolean onLongClick(View v) 
                //this line returns true
                boolean remove = mDataList.contains(user);
                //if I try to remove the user here, its removed
                //this line works as I want
//                mDataList.remove(user);
                Log.d(MainActivity.TAG, "updateDataSet: Contains: "+remove);
                Task<Void> removeUser = NetworkUtils.removeUser(user.getUid());
                removeUser.addOnSuccessListener(new OnSuccessListener<Void>() 
                    @Override
                    public void onSuccess(Void aVoid) 
                        Toast.makeText(mContext, "User removed", Toast.LENGTH_SHORT).show();
                        //mDataList.remove(user);
                        //notifyDataSetChanged();
                    
                );
                return true;
            
        );
    

我也尝试将 onChildRemoved 中返回的用户传递给适配器,但这也不起作用。

public void updateDataSet(User user)
        //this also returns false even the data of this user id displayed
        boolean contains=mDataList.contains(user);
        //this also does not works
        mDataList.remove(user);
        this.notifyDataSetChanged();
    

我的问题是:

1) 我怎样才能从回收站视图列表中删除在长时间单击项目时删除的项目?

2) 我在MainActivity.java 中有List&lt;User&gt; mDataList,在UserAdapter.java 中有一个。 我将MainActivity 中的mDataList 传递给UserAdapter。 这两个在内存中是相同的还是不同的?如果不同,那么更改MainActivity 中的List&lt;user&gt; mDataList(在onChildAdded 中添加新项目)如何更改UserAdapter 中的List&lt;User&gt; mDataList? 非常感谢。 我已尽我所能解决我的问题。

【问题讨论】:

您在哪里调用 onChildRemoved? 我正在将子侦听器附加到主要活动的 onCreate 中的数据库引用。 【参考方案1】:

用 equals() 方法更新你的 User 类:

public class User 
    private String uid;
    private String name;
    private int age;
    public User() 
    public User(String uid, String name, int age) 
        this.uid = uid;
        this.name = name;
        this.age = age;
    
    public User(String name, int age) 
        this.name = name;
        this.age = age;
    
    public String getUid() return uid;
    public void setUid(String uid) this.uid = uid;
    public String getName() return name;
    public void setName(String name) this.name = name;
    public int getAge() return age;
    public void setAge(int age) this.age = age;

    @Override
    public boolean equals(Object obj) 
        if (obj instanceof User) 
            User user= (User) obj;
            return uid.equals(user.getUid());
         else return false;
    

现在更新您的 onChildRemoved 方法:

@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot)  
      User user=dataSnapshot.getValue(User.class);
      user.setUid(dataSnapshot.getKey());
      int index = mDataList.indexOf(user);
      mDataList.remove(index);
      mUserAdapter.notifyDataSetChanged();
    

注意:如果mDataList中不存在uid,则返回-1。

【讨论】:

非常感谢。问题解决了。我想过这个,但没有尝试。你能解释一下为什么我需要重写 equals 方法吗?你对我的第二个问题有什么看法?再次感谢。请为这个问题投票,因为这将对我以后的问题有所帮助。 覆盖equals方法可以直接给你索引而不使用for循环或迭代器。我已经投票了。 谢谢。覆盖 equals 方法后,即使没有获取索引,remove 方法也可以工作。您对我帖子中的第二个问题有何看法? 这取决于你如何在适配器中声明arraylist。如果您使用 new 关键字创建 arraylist,显然它将占用不同的内存,并且如果您只是声明 arrayList 即 List mArrayList; ,在这种情况下它不会占用不同的内存。如果对您有帮助,请接受答案或点赞。 知道了。非常感谢。答案被接受并投票赞成。

以上是关于List<User> 不删除它包含在 RecyclerView 适配器中的 POJO 对象的主要内容,如果未能解决你的问题,请参考以下文章

List中remove()方法移除不了数据,达人快来~

从一个列表中删除元素如果不包含在另一个列表中。 C# [重复]

list 简介及其使用

List<Model> 不包含定义 SingleOrDefaultAsync 和可访问的扩展方法

c# list<user> list中有重复的数据,去掉重复的数据,或删掉重复的数据

如何判断List<String>list中是不是包含某个字符串