RecyclerView Ошибки?
У меня есть Note-App. В основной деятельности примечания будут перечислены с RecyclerView
, Чтобы применить изменения в базе данных я использую FirestoreRecyclerOptions
,
Но у меня есть большая проблема. Во-первых, все отлично работает. Когда элементы ListItems меняются один или несколько раз, все становится запутанным. Затем происходят эти вещи:
- RecyclerViewItems невидимы ( https://www.dropbox.com/s/76e0pi3bgmqdk4u/empty_list.mp4?dl=0)
- RecyclerViewItem не отображается ( https://www.dropbox.com/s/5ai92ypev1509qg/dont_show.mp4?dl=0)
- RecyclerViewItem не удаляется ( https://www.dropbox.com/s/3k2k3ryecfwnqil/dosnt_remove.mp4?dl=0)
В видео вы можете видеть, что все элементы будут работать правильно после прокрутки в представлении переработчика. Не знаю почему? Может быть, обзор переработчика, который действительно перезагружается?
Вот как я настраиваю RecyclerView и когда я вызываю адаптер (фрагмент MainActivity):
public class MainActivity extends AppCompatActivity implements RecyclerItemTouchHelper.RecyclerItemTouchHelperListener {
private FirebaseFirestore db;
public NoteListAdapter adapter;
private RecyclerView recyclerView;
private RecyclerView.LayoutManager recyclerViewLayoutManager;
private ListenerRegistration firestoreListener;
private RecyclerItemTouchHelper.RecyclerItemTouchHelperListener listener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.rvNoteList);
db = FirebaseFirestore.getInstance();
setUpRecyclerView();
}
private void setUpRecyclerView() {
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder().setPersistenceEnabled(true).build();
db.setFirestoreSettings(settings);
Query query = db.collection("users").document(firebase_user_uid).collection("notes");
FirestoreRecyclerOptions<Note> response = new FirestoreRecyclerOptions.Builder<Note>().setQuery(query, Note.class).build();
adapter = new NoteListAdapter(response, MainActivity.this);
recyclerViewLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(recyclerViewLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new CustomRecyclerViewDivider(this, LinearLayoutManager.VERTICAL, 16));
recyclerView.setAdapter(adapter);
ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new RecyclerItemTouchHelper(0, ItemTouchHelper.LEFT, MainActivity.this);
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
adapter.checkIflayoutMustImprove();
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position) {
adapter.removeItem(viewHolder.getAdapterPosition());
}
private void deleteNote(String id) {
db.collection("users").document(firebase_user_uid).collection("notes")
.document(id)
.delete()
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
mFirebaseAnalytics.logEvent(NOTE_DELETED_EVENT, null);
}
});
adapter.notifyDataSetChanged();
}
@Override
public void onStart() {
super.onStart();
adapter.startListening();
}
@Override
public void onStop() {
super.onStop();
adapter.stopListening();
}}
Вот ItemRecyclerTouchHelper:
public class RecyclerItemTouchHelper extends ItemTouchHelper.SimpleCallback {
private RecyclerItemTouchHelperListener listener;
public RecyclerItemTouchHelper(int dragDirs, int swipeDirs, RecyclerItemTouchHelperListener listener) {
super(dragDirs, swipeDirs);
this.listener = listener;
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return true;
}
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (viewHolder != null) {
final View foregroundView = ((NoteViewHolder) viewHolder).viewForeground;
getDefaultUIUtil().onSelected(foregroundView);
}
}
@Override
public void onChildDrawOver(Canvas c, RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder, float dX, float dY,
int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((NoteViewHolder) viewHolder).viewForeground;
getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY,
actionState, isCurrentlyActive);
}
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
final View foregroundView = ((NoteViewHolder) viewHolder).viewForeground;
getDefaultUIUtil().clearView(foregroundView);
}
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder, float dX, float dY,
int actionState, boolean isCurrentlyActive) {
final View foregroundView = ((NoteViewHolder) viewHolder).viewForeground;
getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,
actionState, isCurrentlyActive);
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
listener.onSwiped(viewHolder, direction, viewHolder.getAdapterPosition());
}
@Override
public int convertToAbsoluteDirection(int flags, int layoutDirection) {
return super.convertToAbsoluteDirection(flags, layoutDirection);
}
public interface RecyclerItemTouchHelperListener {
void onSwiped(RecyclerView.ViewHolder viewHolder, int direction, int position);
}}
Я сижу на этой проблеме в течение двух недель, и мне действительно нужна помощь. Я надеюсь, что кто-нибудь может мне помочь. Я даже не знаю, в чем проблема. Проблема в RecyclerView или Firebase или в простой ошибке? Когда вам понадобятся другие файлы, дайте мне знать. Спасибо за помощь.
Изменить NoteListAdapter
открытый класс NoteListAdapter расширяет FirestoreRecyclerAdapter{
private Context context;
private RelativeLayout no_data_layout;
private Animation fadeIn, fadeOut;
public NoteListAdapter(@NonNull FirestoreRecyclerOptions<Note> options, @NonNull Context context) {
super(options);
this.context = context;
}
@Override
protected void onBindViewHolder(@NonNull NoteViewHolder holder, int position, @NonNull Note note) {
holder.bind(context, note, getSnapshots().getSnapshot(position).getId(), note.getNote_image_url());
checkIflayoutMustImprove();
//setAlarms
if (note.getRemindeDate() != null) {
if (note.getRemindeDate().before(new Date())) {
note.setRemindeDate(null);
}
if (note.getRemindeDate() != null) {
Intent i = new Intent(context, TodoNotificationService.class);
i.putExtra(TodoNotificationService.TODOUUID, note.getId());
i.putExtra(TodoNotificationService.TODOTEXT, note.getTitle());
i.putExtra(TodoNotificationService.TODOCONTENT, note.getContent());
MainActivity.createAlarm(context, i, getSnapshots().getSnapshot(position).getId().hashCode(), note.getRemindeDate().getTime());
}
}
if (note.getRemindeDate() == null) {
Intent i = new Intent(context, TodoNotificationService.class);
int id = getSnapshots().getSnapshot(position).getId().hashCode();
MainActivity.deleteAlarm(context, i, id);
}
}
@Override
public int getItemCount() {
return getSnapshots().size();
}
@NonNull
@Override
public NoteViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_note_view, parent, false);
return new NoteViewHolder(view);
}
public void removeItem(int position) {
getSnapshots().getSnapshot(position).getReference().delete();
notifyItemRemoved(position);
checkIflayoutMustImprove();
}}
2 ответа
Так что спасибо за вашу помощь, но никто не мог ответить на это. Я закодировал immersiveMode() в моем приложении. Он устанавливает экран в полноэкранный режим даже при любых взаимодействиях. Я заметил, что все ошибки, которые у меня когда-либо были с RecyclerView, исчезли, когда я удалил методы immersiveMode(). Я не мог сказать почему, но теперь это работает. Но спасибо всем.:)
Поместите эту строку
adapter.notifyDataSetChanged();
внутри вашего
addOnCompleteListener()
так ваш onCompleteListener будет выглядеть так
addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
mFirebaseAnalytics.logEvent(NOTE_DELETED_EVENT, null);
adapter.notifyDataSetChanged();
}
});
если это не сработает, вы должны также опубликовать свой класс адаптера.