0

I believe that the onCreateViewHolder and OnBindViewHolder is not getting run to populate the data.

The null pointer exception is on line 21 of the following code in the CheckInRecentList.java. When debugging, the allCheckIn.size() has 4 entries in it.

The line... checkInLastDateTime.setText(allCheckIn.get(0).getCheckInLastDateTime()); gets the null pointer exception I assume due to checkInLastDateTime being null.

    private void observerSetup() {
        Log.i(TAG, "observerSetup:");
        checkInLastDateTime = getView().findViewById(R.id.checkInLastDateTime);
        checkInTitle = getView().findViewById(R.id.checkInTitle);
        checkInDestinationName = getView().findViewById(R.id.checkInDestinationName);
        checkInComments = getView().findViewById(R.id.checkInComments);
        if(mViewModel.getAllCheckIn() != null)
            mViewModel.getAllCheckIn().observe(getViewLifecycleOwner(), new Observer<List<CheckInTable>>(){
                @Override
                public void onChanged(@Nullable final List<CheckInTable> allCheckIn) {
                    adapter.setCheckInList(allCheckIn);
            }
        });

        mViewModel.getAllCheckIn().observe(getViewLifecycleOwner(), new Observer<List<CheckInTable>>() {
            @Override
            public void onChanged(@Nullable final List<CheckInTable> allCheckIn) {
                        adapter.setCheckInList(allCheckIn);
                        if (allCheckIn.size() > 0) {
                            Log.i(TAG, "onChanged: all check in size greater than zero");
                            checkInLastDateTime.setText(allCheckIn.get(0).getCheckInLastDateTime());
                            Log.i(TAG, "onChanged: running again");
                            checkInDestinationName.setText(allCheckIn.get(0).getCheckInDestinationName());
                            checkInTitle.setText(allCheckIn.get(0).getCheckInTitle());
                            checkInComments.setText(allCheckIn.get(0).getCheckInComments());

                        } else {
                            checkInLastDateTime.setText("None Found");
                        }
                    } 

The logcat entries for the exception is

02-11 09:29:07.888 14867-14867/com.example.checkingin E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.checkingin, PID: 14867
    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
        at com.example.checkingin.CheckInRecentList$4.onChanged(CheckInRecentList.java:240)
        at com.example.checkingin.CheckInRecentList$4.onChanged(CheckInRecentList.java:234)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
        at androidx.lifecycle.LiveData$1.run(LiveData.java:91)
        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)

The full code for the fragment is

package com.example.checkingin;
import android.content.Context;
import android.net.Uri;
import android.nfc.Tag;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProvider.Factory;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
import java.util.List;

import static androidx.constraintlayout.widget.Constraints.TAG;

/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link CheckInRecentList.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link CheckInRecentList#newInstance} factory method to
 * create an instance of this fragment.
 */
public class CheckInRecentList extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    private RecyclerView recyclerView;
    private RecyclerView.Adapter checkInListAdapter;
    //private RecyclerView.LayoutManager layoutManager;
    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;
    private MainViewModel mViewModel;
    private CheckInListAdapter adapter;
    private MainViewModelProviderFactory viewModelFactory;
    private TextView checkInLastDateTime;
    private TextView checkInTitle;
    private TextView checkInDestinationName;
    private TextView checkInComments;

    private OnFragmentInteractionListener mListener;

    public CheckInRecentList() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment CheckInRecentList.
     */
    // TODO: Rename and change types and number of parameters
    public static CheckInRecentList newInstance(String param1, String param2) {
        CheckInRecentList fragment = new CheckInRecentList();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate: On Create");
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    //      These were originally set up from the recycler view add to the fragment
    //          recyclerView = findViewById(R.id.check_in_recent_recycler_view);

                // use this setting to improve performance if you know that changes
                // in content do not change the layout size of the RecyclerView
                //recyclerView.setHasFixedSize(true);
/*
                // use a linear layout manager
                layoutManager = new LinearLayoutManager(this);
                recyclerView.setLayoutManager(layoutManager);
*/
                // specify an adapter (see also next example)
                //checkInListAdapter = new CheckInListAdapter();
     //           recyclerView.setAdapter(checkInListAdapter);
            }

   @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

       mViewModel = new ViewModelProvider(this, viewModelFactory).get(MainViewModel.class);
       Log.i(TAG, "onCreateView: On Create View"); 
       // Inflate the layout for this fragment
              return inflater.inflate(R.layout.fragment_check_in_recent_list, container, false);



    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        Log.i(TAG, "onButtonPressed: ");
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Context context) {

        super.onAttach(context);

        Log.i(TAG, "onAttach: OnAttach");

        viewModelFactory = new MainViewModelProviderFactory(context.getApplicationContext());
        mViewModel = new ViewModelProvider(this, viewModelFactory).get(MainViewModel.class);

        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
       Log.i(TAG,"OnAttach completed");
    }
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        Log.i(TAG, "onActivityCreated: On Activity Created");


        mViewModel = new ViewModelProvider(this, viewModelFactory).get(MainViewModel.class);

        checkInLastDateTime = getView().findViewById(R.id.checkInLastDateTime);
        checkInTitle = getView().findViewById(R.id.checkInTitle);
        checkInDestinationName = getView().findViewById(R.id.checkInDestinationName);
        checkInComments = getView().findViewById(R.id.checkInComments);




        recyclerSetup();
        Log.i(TAG,"OnActivityCreated: Recycler SetUp");
        //listenerSetup();
        //Log.i(TAG, "onActivityCreated: Listener SetUp");
        observerSetup();
        Log.i(TAG, "onActivityCreated: Observer SetUp");


    }
    @Override
    public void onDetach() {
        super.onDetach();
        Log.i(TAG, "onDetach: ");
        mListener = null;

    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }
    private void clearFields() {
        checkInLastDateTime.setText("");
        checkInDestinationName.setText("");
        checkInTitle.setText("");
        checkInComments.setText("");
    }

    private void listenerSetup() {


        ImageButton editCheckInButton = getView().findViewById(R.id.checkInEditButton);
        ImageButton resendCheckInButton = getView().findViewById(R.id.checkInResendButton);

        mViewModel = new ViewModelProvider(this, viewModelFactory).get(MainViewModel.class);
        Log.i(TAG, "listenerSetup: ");
        editCheckInButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
        //put in edit check in logic
            }
        });
        resendCheckInButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
        //put in resend logic
            }
        });

        }

    private void observerSetup() {
        Log.i(TAG, "observerSetup:");
        checkInLastDateTime = getView().findViewById(R.id.checkInLastDateTime);
        checkInTitle = getView().findViewById(R.id.checkInTitle);
        checkInDestinationName = getView().findViewById(R.id.checkInDestinationName);
        checkInComments = getView().findViewById(R.id.checkInComments);
        if(mViewModel.getAllCheckIn() != null)
            mViewModel.getAllCheckIn().observe(getViewLifecycleOwner(), new Observer<List<CheckInTable>>(){
                @Override
                public void onChanged(@Nullable final List<CheckInTable> allCheckIn) {
                    adapter.setCheckInList(allCheckIn);
            }
        });

        mViewModel.getAllCheckIn().observe(getViewLifecycleOwner(), new Observer<List<CheckInTable>>() {
            @Override
            public void onChanged(@Nullable final List<CheckInTable> allCheckIn) {
                        adapter.setCheckInList(allCheckIn);
                        if (allCheckIn.size() > 0) {
                            Log.i(TAG, "onChanged: all check in size greater than zero");
                            checkInLastDateTime.setText(allCheckIn.get(0).getCheckInLastDateTime());
                            Log.i(TAG, "onChanged: running again");
                            checkInDestinationName.setText(allCheckIn.get(0).getCheckInDestinationName());
                            checkInTitle.setText(allCheckIn.get(0).getCheckInTitle());
                            checkInComments.setText(allCheckIn.get(0).getCheckInComments());

                        } else {
                            checkInLastDateTime.setText("None Found");
                        }
                    }
                });
    }
    private void recyclerSetup() {

        Log.i(TAG, "recyclerSetup: ");
        adapter = new CheckInListAdapter(R.layout.fragment_check_in_recent_list);
        RecyclerView recyclerView = getView().findViewById(R.id.check_in_recent_recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        recyclerView.setAdapter(adapter);
        //recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
    }
}

The adapter code is

package com.example.checkingin;


import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.app.Activity;

import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

import static androidx.constraintlayout.widget.Constraints.TAG;

public class CheckInListAdapter extends RecyclerView.Adapter<CheckInListAdapter.ViewHolder>{
    private int checkInListLayout;
    private List<CheckInTable> checkInList;

    public CheckInListAdapter(int layoutId) {
        Log.i(TAG, "CheckInListAdapter: ");
        checkInListLayout = layoutId;
    }

    public void setCheckInList(List<CheckInTable> allCheckIn) {
        checkInList = allCheckIn;
        Log.i(TAG, "setCheckInList: ");
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        return checkInList == null ? 0 : checkInList.size();
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Log.i(TAG, "onCreateViewHolder: ");
        View view = LayoutInflater.from(
                parent.getContext()).inflate(checkInListLayout, parent, false);
        ViewHolder checkInListViewHolder = new ViewHolder(view);
        return checkInListViewHolder;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int listPosition) {
        TextView checkInLastDateTime = holder.checkInLastDateTime;
        TextView checkInTitle = holder.checkInTitle;
        TextView checkInDestinationName = holder.checkInDestinationName;
        TextView checkInComments = holder.checkInComments;
        ImageView checkInEditButton = holder.checkInEditButton;
        ImageView checkInResendButton = holder.checkInResendButton;
        Log.i(TAG, "onBindViewHolder: ");

        checkInLastDateTime.setText(checkInList.get(listPosition).getCheckInLastDateTime());
        checkInTitle.setText(checkInList.get(listPosition).getCheckInTitle());
        checkInDestinationName.setText(checkInList.get(listPosition).getCheckInDestinationName());
        checkInComments.setText(checkInList.get(listPosition).getCheckInComments());
        holder.checkInEditButton.setImageResource(R.drawable.ic_menu_edit);
        holder.checkInResendButton.setImageResource(R.drawable.ic_menu_share);


        ImageButton editCheckInButton = checkInEditButton.findViewById(R.id.checkInEditButton);
        ImageButton resendCheckInButton = checkInResendButton.findViewById(R.id.checkInResendButton);
/*
        editCheckInButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //put in edit check in logic
            }
        }
        );
        resendCheckInButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //put in resend logic
            }
        });
  */
        }

    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView checkInLastDateTime;
        TextView checkInTitle;
        TextView checkInDestinationName;
        TextView checkInComments;
        ImageView checkInEditButton;
        ImageView checkInResendButton;
        ViewHolder(View itemView) {
            super(itemView);
            Log.i(TAG, "ViewHolder: ");
            checkInLastDateTime = itemView.findViewById(R.id.checkInLastDateTime);
            checkInTitle = itemView.findViewById(R.id.checkInTitle);
            checkInDestinationName = itemView.findViewById(R.id.checkInDestinationName);
            checkInComments = itemView.findViewById(R.id.checkInComments);
            checkInEditButton = itemView.findViewById(R.id.checkInEditButton);
            checkInResendButton = itemView.findViewById(R.id.checkInResendButton);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                }
            });
        }
    }
}

The fragment layout is

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CheckInRecentList">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/check_in_recent_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/recycler_view_item"/>


</FrameLayout>

The recycler list xml is

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="0dp">

    <TableLayout
        android:id="@+id/check_in_recent_row"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center|top"
        android:layout_weight="35">
        <TableRow
            android:layout_width="372dp"
            android:layout_height="match_parent"
            android:orientation="horizontal">

            <TextView
                android:layout_width="66dp"
                android:layout_height="20dp"
                android:layout_weight="10"
                android:text="Last Used"
                android:background="#00000000"
                android:textColor="@color/blue"
                />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="20dp"
                android:background="#00000000"
                android:layout_weight="35"
                android:textColor="@color/blue"
                android:text="Title" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="20dp"
                android:background="#00000000"
                android:layout_weight="35"
                android:textColor="@color/blue"
                android:text="Destination" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="20dp"
                android:layout_weight="10"
                android:background="#00000000"
                android:textColor="@color/blue"
                android:text="Edit"/>

            <TextView
                android:layout_height="20dp"
                android:layout_weight="10"
                android:background="#00000000"
                android:textColor="@color/blue"
                android:text="Resend"/>
        </TableRow>
        <TableRow
            android:layout_width="372dp"
            android:layout_height="match_parent"
            android:orientation="horizontal">

            <TextView
            android:id="@+id/checkInLastDateTime"
            android:layout_width="66dp"
            android:layout_height="match_parent"
            android:layout_weight="10"
            android:gravity="center_vertical"
                android:text="TestView"/>

            <TextView
                android:id="@+id/checkInTitle"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="center_vertical"
                android:layout_weight="35"
                android:text="TextView" />

            <TextView
                android:id="@+id/checkInDestinationName"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:gravity="center_vertical"
                android:layout_weight="35"
                android:text="TextView" />

            <ImageButton
                android:id="@+id/checkInEditButton"
                android:layout_width="66dp"
                android:layout_height="40dp"
                android:layout_weight="10"
                android:src="@android:drawable/ic_menu_edit"
                android:tooltipText="Edit Check In" />

            <ImageButton
                android:id="@+id/checkInResendButton"
                android:layout_height="40dp"
                android:layout_weight="10"
                android:src="@android:drawable/ic_menu_share"
                android:tooltipText="Resend Check In" />
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:id="@+id/checkInComments"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="100"
                android:text="TextView" />

        </TableRow>

    </TableLayout>
</LinearLayout>
GeorgeRussell
  • 91
  • 2
  • 10
  • Does this answer your question? [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – TofferJ Feb 11 '20 at 15:46

1 Answers1

1

From what I can see of your code, you are trying to access View widgets that belong to your adapter in your fragment class. That's why it's null.

getView().findViewById(R.id.checkInLastDateTime);

..will be null because checkInLastDateTime does not belong to the fragment's layout but that of the adapter.

This issue stems from how you are implementing your RecyclerView. I'd advise that you make a function call to update the list items from the fragment to the adapter and update them within the adapter.

Further advice is to google and read up on a basic example of how RecyclerViews are implemented for more clarity.

I hope this helps.

Shayne3000
  • 607
  • 8
  • 5