Java 回收器视图中存在重复项,notifydatasetchanged不工作
单击适配器内的布局时,我正在运行事务,但单击布局时,事务成功运行。但它在myJava 回收器视图中存在重复项,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()放在事务之外,但它不起作
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语句。不要创建两个单独的事务。我认为您应该发布另一个问题,其中包含您已经完成的所有新内容,以便我和其他用户可以仔细查看。