RecyclerView中出现重复项,notifyDataSetChanged方法无效。

3

当我点击适配器中的一个布局时,我正在运行一个事务,但是当我点击该布局时,事务成功运行。但它会在我的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) {
                    }
                });
            }
        }
    }
}
2个回答

1

您正在后台线程中调用notifyDataSetChanged(),您需要按照以下方式从ui线程中调用它

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

                notifyDataSetChanged();
            }
        });

只是一个补充:每个UI更改都必须在UI线程上实现。 - Adeel Turk
请问您能否再详细解释一下,我应该如何在我的代码中使用这个? - Jimmy

1
Firebase数据库客户端在后台线程中运行所有网络操作。这意味着您无法在该后台线程中创建或修改视图。您只能在创建这些视图的线程中修改UI。但是,您被允许进行这些更改的线程是主线程。因此,您需要将以下代码行从事务中移出。
notifyDataSetChanged();

注意:整个视图树是单线程的。因此,在调用任何视图上的任何方法时,您必须始终在UI线程上。如果您正在其他线程上工作并希望从该线程更新视图的状态,则应使用处理程序。 您可以在这里找到更多信息。

你尝试过完全将 notifyDataSetChanged(); 方法从事务中移除吗?仍然出现错误 Only the original thread that created a view hierarchy can touch its views. 吗? - Alex Mamo
不,我现在没有遇到这个错误,但是我的回收视图仍然存在重复项。我已经将它放在了事务之外。 - Jimmy
但我只在一个项目上运行,所以我正在更改的唯一UI是列表中的那个,它应该可以工作。 - Jimmy
尝试使用您的逻辑,使代码像**这个**一样简单。 - Alex Mamo
1
我认为你应该发布另一个问题,其中包含你已经完成的所有新内容,这样我和其他用户就可以更仔细地查看它。 - Alex Mamo
显示剩余9条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接