【问题标题】:Duplicate item in recycler view, notifydatasetchanged is not working回收站视图中的重复项目,notifydatasetchanged 不起作用
【发布时间】:2018-11-28 06:49:28
【问题描述】:

我在我的适配器内单击布局时运行事务,但是当我单击布局时,事务运行成功。但它在我的RecyclerView 中创建了另一个项目。我在事务中尝试了 notifydatasetChanged() 但它会产生错误:

CalledFromWrongThreadException: Only the original thread that created a view 
hierarchy can touch its views.

然后我尝试将 notifyDataSetChanged() 放在事务之外,但它不起作用。以下是我正在做的事情:

holder.follow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View view) {
                DatabaseReference mWorkDatabase = 
                FirebaseDatabase.getInstance().getReference()
               .child("WorkforWorkMen").child(work_id).child("follower");
                mWorkDatabase.runTransaction(new Transaction.Handler() {
                    @Override
                    public Transaction.Result doTransaction(MutableData 
                     mutableData) {
                        if(holder.followText.getText().equals("Follow")) {
                            holder.followText.setText("Following");
                            FirebaseAuth mAuth = FirebaseAuth.getInstance();
                            String current_user = 
                            mAuth.getCurrentUser().getUid();
                            DatabaseReference mFollowingDatabase = 
                            FirebaseDatabase.getInstance().getReference()
                  .child("WorkFollowing").child(current_user).child(work_id);
                            final Map fol = new HashMap();
                            fol.put("follower",work_id);
                            mFollowingDatabase.setValue(fol);
                            mutableData.setValue
                  (Integer.parseInt(mutableData.getValue().toString()) + 1);
                        }

                    else {
                            holder.followText.setText("Follow");
                            FirebaseAuth mAuth = FirebaseAuth.getInstance();
                            String current_user = 
                            mAuth.getCurrentUser().getUid();
                            DatabaseReference mFollowingDatabase = 
                            FirebaseDatabase.getInstance().getReference()
                  .child("WorkFollowing").child(current_user).child(work_id);
                            mFollowingDatabase.setValue(null);
                            mutableData.setValue(Integer
                           .parseInt(mutableData.getValue().toString()) - 1);
                        }

                        return Transaction.success(mutableData);
                    }
                    @Override
                    public void onComplete(DatabaseError databaseError, 
                    boolean b, DataSnapshot dataSnapshot) {
                        Toast.makeText(context,"error on complete"+ 
                  String.valueOf(databaseError), Toast.LENGTH_SHORT).show();
                        Log.i("eror here", "onComplete: 
                  "+String.valueOf(databaseError));
                    }
                });
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(context, "here", 
                          Toast.LENGTH_SHORT).show();
                        notifyDataSetChanged();
                    }
                });

            }
        });

我认为当我将数据添加到我的列表时,关注者值的变化会导致它添加一个新项目,但我不确定

 private void loadMessages(){
    if(keys.size() == 0){
        messagesList.clear(); 
        Toast.makeText(getContext(), " size zero no results found", 
    Toast.LENGTH_SHORT).show();
    }
    else {
        messagesList.clear();
        for (int i = 0; i < 5; i++) {
            if (i>=keys.size()){
                Toast.makeText(getContext(), "list is less than 5 item", 
            Toast.LENGTH_SHORT).show();
            }
            else {
                listPos = i;
                String id = keys.get(i);
                mWorkDatabase.child(id).addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        String messageKey = dataSnapshot.getKey();
                        NewWork message = dataSnapshot.getValue(NewWork.class);
                        itemPos++;
                        messagesList.add(message);
                        mAdapter.notifyDataSetChanged();
                        mRecyclerView2.scrollToPosition(messagesList.size() - 1);
                    }
                    @Override
                    public void onCancelled(DatabaseError databaseError) {
                    }
                });
            }
        }
    }
}

【问题讨论】:

    标签: java android firebase firebase-realtime-database android-recyclerview


    【解决方案1】:

    您正在从后台thread 调用notifyDataSetChanged(),您需要从ui thread 调用它,如下所示

    new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
    
                    notifyDataSetChanged();
                }
            });
    

    【讨论】:

    • 只是一个补充:每个ui更改都必须在ui线程上实现
    • 你能解释一下吗,我应该如何在我的代码中使用它
    【解决方案2】:

    Firebase 数据库客户端在后台线程中运行所有网络操作。这意味着您不能在该后台线程中查看createmodify。您只能在创建这些视图的线程中修改 UI。但是,允许您进行这些更改的线程是主线程。所以你需要做的就是把下面这行代码从事务中取出来。

    notifyDataSetChanged();
    

    注意:整个视图树是单线程的。因此,在任何视图上调用任何方法时,您必须始终在 UI 线程上。如果您在其他线程上工作并且想要从该线程更新视图的状态,您应该使用Handler

    您可以找到更多here

    【讨论】:

    • 我明白你的意思,但即使在使用新的 Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void运行() { notifyDataSetChanged(); } });该项目仍在我的点击事件中重复
    • 您是否尝试过将notifyDataSetChanged(); 方法完全退出事务?仍然收到此错误Only the original thread that created a view hierarchy can touch its views.
    • 不,我现在没有收到此错误,但我的回收站视图中仍然出现重复项目。我已经把它放在交易之外了
    • 那很好,说明你的问题解决了一半。关于重复项,要解决此问题,请更改代码的逻辑。创建一个事务并在其中使用该 if 语句。不要创建两个单独的事务。
    • 我认为您应该发布另一个问题,其中包含您已经完成的所有新内容,以便我和其他用户可以仔细查看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 2021-11-02
    相关资源
    最近更新 更多