#java #android #firebase-realtime-database #android-recyclerview
#java #Android #firebase-база данных реального времени #android-recyclerview
Вопрос:
Я пытаюсь удалить данные из моего recyclerview и позволить им обновляться и в мобильном пользовательском интерфейсе. Это приложение для Android. Я могу удалить данные нормально, но мне всегда приходится покидать эту страницу и возвращаться, когда я вношу изменения. Я попытался внести некоторые изменения в метод onChildRemoved, но после внесения этого изменения у меня начались сбои. Что мне делать? Ниже приведен мой код.
MainActivity.java
DatabaseReference databaseReference;
List<DataSnapshot> listData;
RecyclerView recyclerView;
MyCart.MyAdapter adapter;
recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
listData = new ArrayList<>();
adapter = new MyCart.MyAdapter(listData);
adapter.setHasStableIds(true);
GetDataFirebase();
private void GetDataFirebase() {
databaseReference = FirebaseDatabase.getInstance().getReference()
.child("Customers")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("My Cart");
databaseReference.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Items students = dataSnapshot.getValue(Items.class);
listData.add(dataSnapshot);
recyclerView.setAdapter(adapter);
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
int index = listData.indexOf(dataSnapshot);
listData.remove(index);
adapter.notifyDataSetChanged();
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
Класс адаптера
public class MyAdapter extends RecyclerView.Adapter<MyCart.MyAdapter.ViewHolder> {
List<DataSnapshot> list;
public MyAdapter(List<DataSnapshot> List) {
this.list = List;
}
@Override
public void onBindViewHolder(MyCart.MyAdapter.ViewHolder holder, int position) {
final DataSnapshot studentSnapshot = list.get(position);
final Items students = studentSnapshot.getValue(Items.class);
final String list_user_id = studentSnapshot.getKey();
holder.item_name.setText(students.getItem_name());
holder.item_price.setText(students.getItem_price());
Picasso.with(holder.item_image.getContext()).load(students.getItem_image()).placeholder(R.drawable.no_image_two).into(holder.item_image);
holder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DatabaseReference prod_ref = FirebaseDatabase.getInstance().getReference().child("Customers").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("My Cart").child(list_user_id);
prod_ref.removeValue();
adapter.notifyDataSetChanged();
Toast.makeText(MyCart.this, "Item removed from cart", Toast.LENGTH_SHORT).show();
}
});
}
@NonNull
@Override
public MyCart.MyAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cart_item_layout, parent, false);
return new MyCart.MyAdapter.ViewHolder(view);
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView item_name, item_price;
ImageView item_image;
ImageView delete;
public ViewHolder(View itemView) {
super(itemView);
item_name = itemView.findViewById(R.id.item_name);
item_price = itemView.findViewById(R.id.item_price);
item_image = itemView.findViewById(R.id.item_image);
delete = itemView.findViewById(R.id.delete_item);
}
}
@Override
public int getItemCount() {
return list.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return position;
}
}
Комментарии:
1. вызывали ли вы метод notifyDataSetChanged() после удаления данных внутри класса адаптера?
2. Нет, пожалуйста. Позвольте мне попробовать это как можно скорее
3. хорошо, пожалуйста, добавьте код класса адаптера к вопросу тоже
4. Я отредактировал свой вопрос. Когда я добавил метод notifyDataSetChanged(), он все равно разбился. Я что-то упускаю?
5. Если приложение выходит из строя, происходит трассировка стека. Пожалуйста, найдите это в logcat и добавьте в свой вопрос.
Ответ №1:
holder.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DatabaseReference prod_ref = FirebaseDatabase.getInstance().getReference().child("Customers").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("My Cart").child(list_user_id);
prod_ref.removeValue();
//add/modify these two lines here
list.remove(position);
notifyDataSetChanged();
}
});
И еще одно изменение, которое вам нужно сделать
// переместите этот тост в метод onChildRemoved и очистите другой код оттуда
Toast.makeText(MyCart.this, "Item removed from cart", Toast.LENGTH_SHORT).show();
Нравится
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
//remove these line these will raise the exception and Toast here
int index = listData.indexOf(dataSnapshot);
listData.remove(index);
adapter.notifyDataSetChanged();
}
Комментарии:
1. Эй, чувак, ты знаешь, как я мог бы добавить какую-то анимацию при удалении? Я читал о notifyitemremoved, но, похоже, это не работает. Есть предложения?
Ответ №2:
Когда dataSnapshot
не существует в списке, он возвращает -1
. Индекс списка начинается с 0
. Следовательно, вы получаете эту ошибку. Вам нужно добавить сюда защитную проверку, например:
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
int index = listData.indexOf(dataSnapshot);
if(index > 0) {
listData.remove(index);
}
adapter.notifyDataSetChanged();
}
Комментарии:
1. Спасибо за ваш комментарий @Tayyab. Несмотря на то, что сбой прекратился, пользовательский интерфейс не обновляется. Мне все еще нужно покинуть пользовательский интерфейс и вернуться, чтобы увидеть изменения. У вас есть какие-либо предложения?
2. О!, я просто исправляю проблему с исключением. Обновлен код, пожалуйста, проверьте сейчас. Надеюсь, теперь ваша проблема будет решена.
3. Эй, чувак, ты знаешь, как я мог бы добавить какую-то анимацию при удалении? Я читал о notifyitemremoved, но, похоже, это не работает. Есть предложения?
4. Привет, братан, есть какая-нибудь помощь?