2

Я - давний сторонник, первый постер, поэтому надеюсь, что я прав. Я пытаюсь войти в разработку android-firebase и подумал, что лучший способ - выбрать проект и попытаться найти свой путь. Я пытался разработать простое приложение для работы (я врач), что позволит нашей команде просматривать краткие заметки о проделанной работе о наших пациентах, а также позволяет публиковать задания, которые необходимо выполнить для каждого пациент. Я получил большую часть работы, однако, я застрял в какой-то момент. После того как я открываю запись пациента, загружается подробная страница, включающая раздел «комментарии» и раздел «задачи». Оба из них - RecyclerView, содержащие записи «много-к-одному». Проблема, с которой я столкнулся, связана с попыткой удалить один из элементов «задач» при нажатии (поэтому он удален из списка и больше не выполняется). Я продолжаю получать исключение Null Pointer. Проблема в том, что я не совсем уверен, правильный ли код. Я все еще участвую, поэтому мой код включает в себя множество разделов из разных мест, в которых я играл (я начал с образца базы данных android-firebase из github, а также многих других онлайн-источников) и переписал (после много взлома и исправления), чтобы заставить его работать. Извините за длинное введение. Итак, вот что у меня есть до сих пор (не полный код, просто разделы, которые, по моему мнению, значительны). Надеюсь, кто-то может мне помочь.Null Pointer Исключение при попытке удалить элемент в 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); 

Error Log

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

Я не эксперт в области firebase, но из вашего кода я не вижу, что вы назначаете что-либо своему mAdapter. Вот почему у вас есть NPE позже, когда вы обращаетесь к нему в свой метод removeItem.

Пример того, как firebase адаптер может быть использован: http://www.coderefer.com/firebaseui-android-firebase-database/

+0

Спасибо за быстрый ответ ... но я пытался понять это ... попытался найти его в Интернете ... но я Я не уверен, что смогу понять, как это делается .. может быть более конкретным? Еще раз ... thank u – hanykasem

+0

просто добавил пример, где вы можете найти способ создания экземпляра адаптера –

+0

Я все еще не мог заставить его работать (все еще пытаюсь выяснить, где и как его реализовать) ... Я предполагаю, что это нужно зайти в класс TaskAdapter ... может быть, заменить мой существующий метод TaskAdapter ... попытаюсь понять это ... но по крайней мере я знаю, в какое направление идти – hanykasem

Смежные вопросы