Java 回收器视图中存在重复项,notifydatasetchanged不工作

Java 回收器视图中存在重复项,notifydatasetchanged不工作,java,android,firebase,firebase-realtime-database,android-recyclerview,Java,Android,Firebase,Firebase Realtime Database,Android Recyclerview,单击适配器内的布局时,我正在运行事务,但单击布局时,事务成功运行。但它在myRecyclerView中创建了另一项。我在事务内尝试了notifydatasetChanged(),但它创建了一个错误: CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 然后我尝试将notifyDataSetChanged()放在事务之外,但它不起作

单击适配器内的布局时,我正在运行事务,但单击布局时,事务成功运行。但它在my
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) {
                    }
                });
            }
        }
    }
}
private void loadMessages(){
如果(keys.size()==0){
messagesList.clear();
Toast.makeText(getContext(),“大小为零,未找到结果”,
吐司。长度(短)。show();
}
否则{
messagesList.clear();
对于(int i=0;i<5;i++){
如果(i>=keys.size()){
Toast.makeText(getContext(),“列表少于5项”,
吐司。长度(短)。show();
}
否则{
listPos=i;
String id=keys.get(i);
mWorkDatabase.child(id).addValueEventListener(新的ValueEventListener(){
@凌驾
公共void onDataChange(DataSnapshot DataSnapshot){
字符串messageKey=dataSnapshot.getKey();
NewWork message=dataSnapshot.getValue(NewWork.class);
itemPos++;
messagesList.add(消息);
mAdapter.notifyDataSetChanged();
mrecyclervew2.scrollToPosition(messagesList.size()-1);
}
@凌驾
已取消的公共void(DatabaseError DatabaseError){
}
});
}
}
}
}

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

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

                notifyDataSetChanged();
            }
        });

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

notifyDataSetChanged();
注意:整个视图树是单线程的。因此,在任何视图上调用任何方法时,必须始终处于UI线程上。如果您正在其他线程上工作,并且希望从该线程更新视图的状态,则应使用
处理程序


您可以找到更多信息。

只是一个补充:每个ui更改都必须在ui线程上实现。您能再解释一下吗,我应该如何在我的代码中使用它我明白你想说的,但我仍然有点困惑,因为即使使用了新的处理程序(Looper.getMainLooper()).post(newrunnable()){@Override public void run(){notifyDataSetChanged();}}});在我的点击事件中,该项仍在重复您是否尝试获取
notifyDataSetChanged()
方法完全退出事务?是否仍会出现此错误
只有创建视图层次结构的原始线程才能接触其视图。
?不,我现在没有遇到此错误,但我的回收器视图中仍会出现重复项。我已将其放置在事务之外。这很好,这意味着您的问题有一半是我的问题解决了。关于重复,要修复此问题,请更改代码的逻辑。创建一个事务,并在其中使用if语句。不要创建两个单独的事务。我认为您应该发布另一个问题,其中包含您已经完成的所有新内容,以便我和其他用户可以仔细查看。