我的recyclerview的每个项目都有一个数量选择器。滚动时数量值因回收而发生变化。因此,我正在尝试使用最新值和更新来更新地图。每当移除或更改子项时,notifyItemChanged都会显示该位置。
我正在使用ChildEventListener来监听孩子的变化。但是当onChildChanged发生单个更改时,将继续打印util onDestroy。
我该如何解决这个问题?请指导我......
private void cartListener(int pos) {
cartRef = mCustDB.child(Email).child("mycart");
cartRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
Timber.d("onChildChanged > " + dataSnapshot.getKey());
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
logcat的
01-31 16:34:58.759 27963-27963/? D/BrowsePresenter: onChildChanged > c02p02
01-31 16:34:58.782 27963-27963/? D/BrowsePresenter: onChildChanged > c02p02
01-31 16:34:59.399 27963-27963/? D/BrowsePresenter: onChildChanged > c02p02
01-31 16:34:59.409 27963-27963/? D/BrowsePresenter: onChildChanged > c02p02
01-31 16:35:00.055 27963-27963/? D/BrowsePresenter: onChildChanged > c02p02
01-31 16:35:01.959 27963-27963/? D/BrowsePresenter: onChildChanged > c02p02
01-31 16:35:01.970 27963-27963/? D/BrowsePresenter: onChildChanged > c02p02
01-31 16:35:02.599 27963-27963/? D/BrowsePresenter: onChildChanged > c02p02
注意
我只更改了一次数据。但是对于每次更改,方法都会不停地触发,直到我删除侦听器!
更新
问题在于addToCart
方法,因为如果我直接在firebase中更新值。听众只被解雇了两次。
如果我使用以下方法更新值。它被多次触发,直到我删除监听器。
public void addToCart(Product item, int quantity, int position) {
cartRef = mCustDB.child(Email).child("mycart");
cartRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String prodID = null;
List<String> mKey = new ArrayList<>();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
prodID = postSnapshot.getKey();
mKey.add(prodID);
}
if (!mKey.contains(item.productID())) {
Cart mycart = new Cart(item.productID(), 1);
cartRef.updateChildren(mycart.toMap());
Timber.d("updateChildren >> ");
} else {
if (quantity == 0) {
Timber.d("Remove >> " + item.productID());
cartRef.child(item.productID()).removeValue();
} else {
Timber.d("INCREASE >> " + item.productID() + quantity);
cartRef.child(item.productID()).setValue(quantity);
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
CART
public class Cart {
public String productID;
public int quantity = 0;
public Cart() {
}
public Cart(String productID, int quantity) {
this.productID = productID;
this.quantity = quantity;
}
public Cart(String productID) {
this.productID = productID;
}
@Exclude
public Map<String, Object> toMap() {
HashMap<String, Object> result = new HashMap<>();
result.put(productID , quantity);
return result;
}
}
答案 0 :(得分:0)
如果您在某个地方一次又一次地使用它,请检查您为eventListner
设置的位置,而不是将it functions
的次数称为eventListner
。生命周期。
答案 1 :(得分:0)
这是因为在每次调用addToCard()时都会添加一个新的侦听器,因此必须删除以前的侦听器,如下所示:
public void addToCart(Product item, int quantity, int position) {
// Add a new propery for the listener
if (cartRef != null && valueEventListener != null) {
cartRef.removeEventListener(valueEventListener);
}
cartRef = mCustDB.child(Email).child("mycart");
valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String prodID = null;
List<String> mKey = new ArrayList<>();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
prodID = postSnapshot.getKey();
mKey.add(prodID);
}
if (!mKey.contains(item.productID())) {
Cart mycart = new Cart(item.productID(), 1);
cartRef.updateChildren(mycart.toMap());
Timber.d("updateChildren >> ");
} else {
if (quantity == 0) {
Timber.d("Remove >> " + item.productID());
cartRef.child(item.productID()).removeValue();
} else {
Timber.d("INCREASE >> " + item.productID() + quantity);
cartRef.child(item.productID()).setValue(quantity);
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
};
cartRef.addValueEventListener(valueEventListener);
}
答案 2 :(得分:-1)
这会对你有所帮助
将Listner ChildEventListener连接到ValueEventListener。
cartRef = mCustDB.child(Email).child("mycart");
cartRef.addChildEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Timber.d("onChildChanged > " + dataSnapshot.getKey());
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
答案 3 :(得分:-2)
这看起来像是通过向节点添加侦听器,然后在侦听器中更新同一节点来引发循环的情况。
在这种情况下,它是cartRef
方法中的addToCart()
。 ValueEventListener
已添加cartRef
,onDataChange
中的代码会更新cartRef
下的数据,因此侦听器会不断触发自身。
在决定如何进行之前,您的听众似乎要检查购物车的状态;也许避免循环的最简单方法是添加一个单值事件监听器,这样你仍然可以检查,但避免循环。
cartRef.addListenerForSingleValueEvent(new ValueEventListener() {
// same listener as before
....