我有一个用于更改数据库条目messageText
的代码:
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.edit:
AdapterView.AdapterContextMenuInfo tm = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int position = tm.position;
final DatabaseReference ref = adapter.getRef(position);
ref.child("messageUserId").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (FirebaseAuth.getInstance().getCurrentUser().getUid().equals(dataSnapshot.getValue().toString())) {
ref.child("messageText").addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
input.setText(dataSnapshot.getValue().toString());
sendMessage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ref.child("messageText").setValue(input.getText().toString());
input.getText().clear();
Toast.makeText(Chat.this, "Изменено", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
break;
}
return false;
}
代码ref.child("messageText").setValue(input.getText().toString())
的效果很好,但是在代码重新启动之后,
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
input.setText(dataSnapshot.getValue().toString());
一切都转了一圈-messageText
的数据被插入EditText
input
中,我可以再次更改文本。
如何在第一次更改messageText
之后停止执行代码?
答案 0 :(得分:1)
ValueEventListener的onDataChange()方法:
将使用此位置的数据快照调用此方法。每次数据更改时也会调用它。
换句话说,即使它是写,更新或删除操作,也会触发此方法。在您的情况下也是如此,您正在使用相同的引用ref.child("messageText")
来添加数据并侦听更改,因此这就是您的行为。这是一遍又一遍地发生。为了解决这个问题,您需要通过创建两个不同的事件来更改代码的逻辑。 onClick可以将数据写入数据库并附加侦听器,从而使其与该事件无关。
答案 1 :(得分:0)
正确的代码:
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.edit:
AdapterView.AdapterContextMenuInfo tm = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int position = tm.position;
editText = adapter.getRef(position);
editText.child("messageUserId").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (FirebaseAuth.getInstance().getCurrentUser().getUid().equals(dataSnapshot.getValue())) {
editText.child("messageText").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
input.setText(dataSnapshot.getValue().toString());
editMessage();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
} else {
Toast.makeText(Chat.this, "Запрещено", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
return true;
}
private void editMessage() {
sendMessage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
editText.child("messageText").setValue(input.getText().toString());
Toast.makeText(Chat.this, "Изменено", Toast.LENGTH_SHORT).show();
input.getText().clear();
sendMessage();
}
});
}
private void sendMessage() {
sendMessage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (input.getText().toString().trim().equals("")) {
Toast.makeText(Chat.this, getString(R.string.edittext_null), Toast.LENGTH_SHORT).show();
} else {
FirebaseDatabase.getInstance()
.getReference()
.push()
.setValue(new ChatMessage(input.getText().toString(),
Objects.requireNonNull(FirebaseAuth.getInstance().getCurrentUser()).getDisplayName(),
FirebaseAuth.getInstance().getCurrentUser().getUid(),
payload,
avatar,
uploadedAttach
));
input.setText("");
}
}
});
}
必须简单地将其原始操作返回到按钮,并使用addListenerForSingleValueEvent
代替addValueEventListener
。