我是一位长期追随者,第一次发布海报,所以我希望我能做到这一点。我正在尝试进入android-firebase开发,并认为最好的方法是选择一个项目并尝试找到我的方式。我一直在努力开发一个简单的工作应用程序(我是一名医生),这将允许我们的团队查看关于我们住院病人的简要进展记录,并且还允许我们发布每个需要执行的任务。患者。我已经完成了大部分工作,但是,我一度陷入困境。打开患者记录后,会加载详细信息页面,其中包括“评论”部分和“任务”部分。这两个都是包含多对一条目的RecyclerViews。我面临的问题与在单击时删除其中一个“任务”项目有关(因此它已从列表中删除,并且不再处于待处理状态)。我一直得到一个空指针异常。问题是,我不完全确定我的代码是否正确。我还在学习,所以我的代码包含了很多来自不同地方的部分(我从github开始使用android-firebase数据库样本,以及许多其他在线资源),并重新编写(之后)让它发挥作用的很多破坏和修复。很抱歉很长的介绍。所以,这是我到目前为止所得到的(不是完整的代码,只是我认为重要的部分)。我希望有人可以帮助我。
postDetailActivity.java
private static class TaskViewHolder extends RecyclerView.ViewHolder {
public TextView dateView;
public TextView bodyView;
public ImageButton checkView;
public TaskViewHolder(View itemView, final TaskAdapter mTaskAdapter) {
super(itemView);
dateView = (TextView) itemView.findViewById(R.id.task_date);
bodyView = (TextView) itemView.findViewById(R.id.task_body);
checkView = (ImageButton) itemView.findViewById(R.id.check);
checkView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "Adapter Position:" + getAdapterPosition());
mTaskAdapter.removeItem(getAdapterPosition());
}
});
}
private static class TaskAdapter extends RecyclerView.Adapter<TaskViewHolder> {
private Context mContext;
private DatabaseReference mDatabaseReference;
private DatabaseReference mTaskReference;
private ChildEventListener mChildEventListener;
private FirebaseRecyclerAdapter<Task, TaskViewHolder> mAdapter;
private List<String> mTaskIds = new ArrayList<>();
private List<Task> mTasks = new ArrayList<>();
public TaskAdapter(final Context context, DatabaseReference ref) {
mContext = context;
mDatabaseReference = ref;
// Create child event listener
// [START child_event_listener_recycler]
ChildEventListener childEventListener = new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
// A new task has been added, add it to the displayed list
Task task = dataSnapshot.getValue(Task.class);
// [START_EXCLUDE]
// Update RecyclerView
mTaskIds.add(dataSnapshot.getKey());
mTasks.add(task);
notifyItemInserted(mTasks.size() - 1);
// [END_EXCLUDE]
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());
// A task has changed, use the key to determine if we are displaying this
// task and if so displayed the changed task.
Task newTask = dataSnapshot.getValue(Task.class);
String taskKey = dataSnapshot.getKey();
// [START_EXCLUDE]
int taskIndex = mTaskIds.indexOf(taskKey);
if (taskIndex > -1) {
// Replace with the new data
mTasks.set(taskIndex, newTask);
// Update the RecyclerView
notifyItemChanged(taskIndex);
} else {
Log.w(TAG, "onChildChanged:unknown_child:" + taskKey);
}
// [END_EXCLUDE]
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());
// A task has changed, use the key to determine if we are displaying this
// task and if so remove it.
String taskKey = dataSnapshot.getKey();
// [START_EXCLUDE]
int taskIndex = mTaskIds.indexOf(taskKey);
if (taskIndex > -1) {
// Remove data from the list
mTaskIds.remove(taskIndex);
mTasks.remove(taskIndex);
// Update the RecyclerView
notifyItemRemoved(taskIndex);
} else {
Log.w(TAG, "onChildRemoved:unknown_child:" + taskKey);
}
// [END_EXCLUDE]
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());
// A task has changed position, use the key to determine if we are
// displaying this task and if so move it.
Task movedTask = dataSnapshot.getValue(Task.class);
String taskKey = dataSnapshot.getKey();
// ...
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "postTasks:onCancelled", databaseError.toException());
Toast.makeText(mContext, "Failed to load tasks.",
Toast.LENGTH_SHORT).show();
}
};
ref.addChildEventListener(childEventListener);
// [END child_event_listener_recycler]
// Store reference to listener so it can be removed on app stop
mChildEventListener = childEventListener;
}
@Override
public TaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.item_task, parent, false);
return new TaskViewHolder(view, this);
}
@Override
public void onBindViewHolder(TaskViewHolder holder, int position) {
Task task = mTasks.get(position);
holder.dateView.setText(task.date);
holder.bodyView.setText(task.text);
}
@Override
public int getItemCount() {
return mTasks.size();
}
public void cleanupListener() {
if (mChildEventListener != null) {
mDatabaseReference.removeEventListener(mChildEventListener);
}
}
public void removeItem(int position) {
mAdapter.getRef(position).removeValue();
mAdapter.notifyItemRemoved(position);
错误记录
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.firebase.database.DatabaseReference com.firebase.ui.database.FirebaseRecyclerAdapter.getRef(int)' on a null object reference
at com.hanykasem.omfsrounds.PostDetailActivity$TaskAdapter.removeItem(PostDetailActivity.java:606)
at com.hanykasem.omfsrounds.PostDetailActivity$TaskViewHolder$1.onClick(PostDetailActivity.java:451)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
就像我说的那样,我不确定问题出在哪里,而且我已经尝试了很多东西来解决问题,但不能。任何帮助都将受到高度赞赏。
非常感谢。
答案 0 :(得分:1)
我不是firebase的专家,但是从你的代码中我看不出你在 mAdapter 字段中分配了什么。这就是为什么稍后在 removeItem 方法中访问NPE时使用NPE的原因。
有关如何使用firebase适配器的示例: http://www.coderefer.com/firebaseui-android-firebase-database/