我在recyclerview中显示数据。我正在使用Firebase Firestore。这是我在MainActivity中设置适配器的方式:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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);
}
这是我的适配器:
public class NoteListAdapter extends FirestoreRecyclerAdapter<Note, NoteListAdapter.NoteViewHolder>{
private Context context;
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.title.setText(note.getTitle());
holder.content.setText(note.getContent());
}
@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);
}
public class NoteViewHolder extends RecyclerView.ViewHolder {
public TextView title, content;
public ImageView bg_note_image;
public RelativeLayout viewBackground, viewForeground;
public NoteViewHolder(View view) {
super(view);
title = view.findViewById(R.id.tvTitle);
content = view.findViewById(R.id.tvContent);
bg_note_image = view.findViewById(R.id.note_image_view);
viewBackground = view.findViewById(R.id.view_background);
viewForeground = view.findViewById(R.id.view_foreground);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DocumentSnapshot snapshot = getSnapshots().getSnapshot(getAdapterPosition());
Note note = snapshot.toObject(Note.class);
String id = getSnapshots().getSnapshot(getAdapterPosition()).getId();
MainActivity.updateNote(id, note);
return;
}
});
}
}}
所以我的应用程序崩溃了,多数民众赞成在此行引起的:
DocumentSnapshot snapshot = getSnapshots().getSnapshot(getAdapterPosition());
这是错误:
09-06 21:09:11.976 19959-19959/com.test.test.test E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.test.test.test, PID: 19959
java.lang.ArrayIndexOutOfBoundsException: length=10; index=-1
at java.util.ArrayList.get(ArrayList.java:413)
at com.firebase.ui.common.BaseObservableSnapshotArray.getSnapshot(BaseObservableSnapshotArray.java:70)
at com.raycroud.notes.notes.adapter.NoteListAdapter$NoteViewHolder$1.onClick(NoteListAdapter.java:97)
at android.view.View.performClick(View.java:5685)
at android.view.View$PerformClick.run(View.java:22481)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:241)
at android.app.ActivityThread.main(ActivityThread.java:6274)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
在getAdapterPosition()下的documentation中,有一个注释:
Note that if you've called notifyDataSetChanged(), until the next layout pass, the return value of this method will be NO_POSITION.
因此,现在当我不想崩溃我的应用程序时,必须像这样更新ViewHolder中的OnClick:
@Override
public void onClick(View view) {
if (getAdapterPosition() == RecyclerView.NO_POSITION) {
return;
}
DocumentSnapshot snapshot = getSnapshots().getSnapshot(getAdapterPosition());
Note note = snapshot.toObject(Note.class);
String id = getSnapshots().getSnapshot(getAdapterPosition()).getId();
MainActivity.updateNote(id, note);
return;
}
此代码有效,该应用程序不再崩溃。但是当错误通常消失时,我无法再单击“项目”。在查看代码时,我认为这是合乎逻辑的,因为修饰符位置返回
-1
或NO_POSITION
。那么现在是我的Queston如何解决整个错误?我应该怎么做才能使应用程序不会崩溃并且可以单击“项目”? 最佳答案
我不确定为什么适配器位置无效(稍后应进行调查),但是您可以通过改进代码来“解决”此问题:
将NoteViewHolder
移到单独的类中
将bind(Note note, String id)
方法添加到NoteViewHolder
并将这些值存储为可变字段
将匿名内部类更改为setOnClickListener(this)
并在NoteViewHolder
中实现单击侦听器
点击监听器如下所示
在onBindViewHolder
中,使用注释和ID呼叫bind
NoteViewHolder
:
public final class NoteViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
// ...
private Note note;
private String id;
public NoteViewHolder(View itemView) {
super(itemView);
// ...
itemView.setOnClickListener(this);
}
public void bind(Note note, String id) {
this.note = note;
this.id = id;
title.setText(note.getTitle());
content.setText(note.getContent());
}
@Override
public void onClick(View v) {
MainActivity activity = (MainActivity) itemView.getContext(); // You really shouldn't do this, but I don't know what you're building
activity.updateNote(id, note);
}
}