由于每次ValueEventListener
中的数据更新时都会触发Firebase Database
,因此在RecyclerView
显示时完成新上传时也会调用Upload
。我这样做的方式现在会导致重复输入,因为mUploads List
中的ArrayList
个对象已经是。上传完成后,将再次查询整个数据库,并将所有项目添加到已存在的Arraylist
我不知道如何解决此问题。每次触发ValueEventListener时我应该创建一个新的ValueEventListener
还是需要一个完全不同的回调?
另外,mAdapter.notifyItemRemoved
会干扰我的ValueEventListener
来电,因为public class ImagesActivity extends AppCompatActivity implements ImageAdapter.OnItemClickListener {
private RecyclerView mRecyclerView;
private ImageAdapter mAdapter;
private ProgressBar mProgressCircle;
private DatabaseReference mDatabaseRef;
private FirebaseStorage mStorage;
private List<Upload> mUploads;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_images);
mUploads = new ArrayList<>();
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mProgressCircle = findViewById(R.id.progress_circle);
mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads");
mStorage = FirebaseStorage.getInstance();
mDatabaseRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Upload upload = postSnapshot.getValue(Upload.class);
upload.setKey(postSnapshot.getKey());
mUploads.add(upload);
}
mAdapter = new ImageAdapter(ImagesActivity.this, mUploads);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(ImagesActivity.this);
mProgressCircle.setVisibility(View.INVISIBLE);
}
@Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(ImagesActivity.this, databaseError.getMessage(), Toast.LENGTH_LONG).show();
mProgressCircle.setVisibility(View.INVISIBLE);
}
});
}
@Override
public void onDeleteClick(final int position) {
Upload selectedItem = mUploads.get(position);
final String selectedKey = selectedItem.getKey();
StorageReference imageRef = mStorage.getReferenceFromUrl(selectedItem.getImageUrl());
imageRef.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
mDatabaseRef.child(selectedKey).removeValue();
mUploads.remove(position);
mAdapter.notifyItemRemoved(position);
}
});
}
}
会在我删除内容后立即触发。
function MakeMargin(props) {
return theme.spacing[props]
}
答案 0 :(得分:3)
addValueEventListener
添加数据之前清除 mDatabaseRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
mUploads.clear(); //change here
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Upload upload = postSnapshot.getValue(Upload.class);
upload.setKey(postSnapshot.getKey());
mUploads.add(upload);
}
mAdapter = new ImageAdapter(ImagesActivity.this, mUploads);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(ImagesActivity.this);
mProgressCircle.setVisibility(View.INVISIBLE);
}
console.log(object)
答案 1 :(得分:2)
试试这个
在addValueEventListener之前清除arraylist mUploads.clear()
,如下所示
mUploads.clear();
答案 2 :(得分:2)
而不是使用ValueEventListener
考虑附加ChildEventListener
。为添加,更改或删除的各个子节点触发此类型的侦听器。
当您最初附加ChildEventListener
时,将为侦听器匹配的每个子项调用其onChildAdded
。然后,当您稍后将子节点添加到数据库时,将仅使用现有子再次调用。onChildAdded
。这使得更新UI变得非常容易,只需将新子项添加到适配器即可。
ChildEventListener
也有一个onChildChanged
事件,当特定孩子更改时会触发该事件。在这里,该方法仅使用现有子项触发,再次使得更新适配器中的该子项变得容易。
有关此类侦听器的详情,请参阅Firebase文档中的listen for child events。
答案 3 :(得分:1)
您可以使用addListenerForSingleValueEvent()
这将读取一次数据,如果您想刷新数据,可以再次调用,以获取更多信息
Firebase - read data once
答案 4 :(得分:1)
我建议您使用addListenerForSingleValueEvent
以便一次性提取数据,最后添加addChildEventListener
并覆盖onChildAdded
,这样也会获取新的添加项,我认为这样比清除列表和重新充气Recyclerview更好
结帐代码
mDatabaseRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Upload upload = postSnapshot.getValue(Upload.class);
upload.setKey(postSnapshot.getKey());
mUploads.add(upload);
}
mAdapter = new ImageAdapter(ImagesActivity.this, mUploads);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(ImagesActivity.this);
mProgressCircle.setVisibility(View.INVISIBLE);
mDatabaseRef.addChildEventListener(new ChildEventListener(){
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
Upload upload = postSnapshot.getValue(Upload.class);
upload.setKey(postSnapshot.getKey());
mUploads.add(upload);
}
})
}
@Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(ImagesActivity.this, databaseError.getMessage(), Toast.LENGTH_LONG).show();
mProgressCircle.setVisibility(View.INVISIBLE);
}
});