I am getting a null exception pointer in the RecyclerView.java code for my application. I have attached a screen shot of the debug entries at the point of the exception. As you can see, the holder object is null when executing the holder.shouldIngnore() method.
The application has two fragments (each with different recycler views with LiveData) within another fragment within an activity that is using a tablayout.
I suspect the issue with with identifying the child fragments and need help to resolve.
Have provided as much relevant information as possible to assist. This is my first attempt at two fragments within a fragment.
I only included the first child fragment code in order to fit within the StackOverFlow size limit. The second fragment mirrors the first fragment.

[![Debug screenshot][2]][2]
LogcatEntries
2020-04-02 07:44:27.814 10294-10294/com.grgapps.checkingin E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.grgapps.checkingin, PID: 10294
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean androidx.recyclerview.widget.RecyclerView$ViewHolder.shouldIgnore()' on a null object reference
at androidx.recyclerview.widget.RecyclerView.findMinMaxChildLayoutPositions(RecyclerView.java:4311)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4045)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3849)
at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404)
at android.view.View.layout(View.java:17523)
at android.view.ViewGroup.layout(ViewGroup.java:5612)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17523)
at android.view.ViewGroup.layout(ViewGroup.java:5612)
The following is the frame layout within the activity tab (fragment_check_in_new_recipients.xml)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CheckInNewRecipients">
<!-- TODO: Update blank fragment layout -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/fragment_contacts_selection_list_display" />
<include layout="@layout/fragment_contacts_filter_and_display" />
</LinearLayout>
</FrameLayout>
The following is the first child frame (fragment_contacts_selection_list_display.xml) within the frame from the activity tab.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="200dp"
tools:context=".ContactsSelectionListDisplay">
<!-- TODO: Update blank fragment layout -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/check_in_recipient_selection_list_recycler_view"
android:layout_width="match_parent"
android:layout_height="200dp"
android:divider="#467FD7"
android:dividerHeight="10dp"
tools:listitem="@layout/recycler_view_check_in_recipient_selected_list"/>
</FrameLayout>
The following is the second child fragment (fragment_contacts_filter_and_display.xml) within the tabs fragment.
<?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="350dp"
tools:context=".ContactsFilterAndDisplay">
<!-- TODO: Update blank fragment layout -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="108dp">
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="55dp"
android:orientation="horizontal">
</RadioGroup>
<RadioButton
android:id="@+id/radio_all_contacts"
android:layout_width="80dp"
android:layout_height="55dp"
android:layout_marginTop="44dp"
android:layout_marginEnd="328dp"
android:buttonTint="#2196F3"
android:drawableTint="#2196F3"
android:onClick="onRadioButtonClicked"
android:text="@string/radio_contact_filter_all"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<RadioButton
android:id="@+id/radio_app_users"
android:layout_width="100dp"
android:layout_height="55dp"
android:layout_marginTop="44dp"
android:layout_marginEnd="228dp"
android:buttonTint="#2196F3"
android:drawableTint="#2196F3"
android:onClick="onRadioButtonClicked"
android:text="@string/radio_contact_filter_app_users"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<RadioButton
android:id="@+id/radio_by_group"
android:layout_width="100dp"
android:layout_height="55dp"
android:layout_marginTop="44dp"
android:layout_marginEnd="120dp"
android:buttonTint="#2196F3"
android:drawableTint="#2196F3"
android:onClick="onRadioButtonClicked"
android:text="@string/radio_contact_filter_by_group"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<RadioButton
android:id="@+id/radio_filter_search"
android:layout_width="100dp"
android:layout_height="55dp"
android:layout_marginStart="304dp"
android:layout_marginTop="44dp"
android:buttonTint="#2196F3"
android:drawableTint="#2196F3"
android:onClick="onRadioButtonClicked"
android:text="@string/radio_contact_filter_search"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView14"
android:layout_width="match_parent"
android:layout_height="30dp"
android:text="@string/title_contacts_filter"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/check_in_recipient_contacts_list_recycler_view"
android:layout_width="match_parent"
android:layout_height="250dp"
android:divider="#467FD7"
android:dividerHeight="10dp"
tools:listitem="@layout/recycler_view_check_in_contacts_list" />
</LinearLayout>
</FrameLayout>
The following is the java code for the first fragment (CheckInNewRecipients) within the tablayout.
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link CheckInNewRecipients.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link CheckInNewRecipients#newInstance} factory method to
* create an instance of this fragment.
*/
public class CheckInNewRecipients 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";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public CheckInNewRecipients() {
// Required empty public constructor
Log.i(TAG, "CheckInNewRecipients: ");
}
/**
* 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 CheckInNewRecipients.
*/
// TODO: Rename and change types and number of parameters
public static CheckInNewRecipients newInstance(String param1, String param2) {
CheckInNewRecipients fragment = new CheckInNewRecipients();
Log.i(TAG, "CheckInNewRecipients newInstance: ");
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, "CheckInNewRecipients onCreate: ");
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.i(TAG, "CheckInNewRecipients onCreateView: ");
// Inflate the layout for this fragment
ContactsSelectionListDisplay contactsSelectionListDisplay = new
ContactsSelectionListDisplay(R.layout.activity_check_in_new, getActivity());
ContactsFilterAndDisplay contactsFilterAndDisplay =
new ContactsFilterAndDisplay(R.layout.activity_check_in_new, getActivity());
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.beginTransaction().add(R.id.check_in_recipient_contacts_list_recycler_view,
contactsFilterAndDisplay).commit();
fm.beginTransaction().add(R.id.check_in_recipient_selection_list_recycler_view,
contactsSelectionListDisplay).commit();
return inflater.inflate(R.layout.fragment_check_in_new_recipients, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
Log.i(TAG, "CheckInNewRecipients onButtonPressed: ");
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
Log.i(TAG, "CheckInNewRecipients onAttach: ");
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.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);
}
}
The following is the java code for the first child fragment (ContactsSelectionListDisplay.java)
/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link ContactsSelectionListDisplay.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link ContactsSelectionListDisplay#newInstance} factory method to
* create an instance of this fragment.
*/
public class ContactsSelectionListDisplay 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";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private RecyclerView recyclerView;
private RecyclerView.Adapter checkInContactSelectionListAdapter;
//private RecyclerView.LayoutManager layoutManager;
private MainViewModel mViewModel;
private CheckInContactsSelectionListDisplayAdapter mAdapter;
private MainViewModelProviderFactory viewModelFactory;
private TextView checkInContactsPhotoThumbnail;
private TextView checkInContactsDisplayLastName;
private TextView checkInContactsDisplayFirstName;
private TextView checkInContactsListGroups;
private Context context;
private ContactsSelectionListDisplay.OnFragmentInteractionListener mListener;
public ContactsSelectionListDisplay(int layoutID, Context context) {
// Required empty public constructor
Log.i(TAG, "ContactsSelectionListDisplay: ");
}
/**
* 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 ContactsSelectionLIstDisplay.
*/
// TODO: Rename and change types and number of parameters
public static ContactsSelectionListDisplay newInstance(int layoutid, Context context) {
ContactsSelectionListDisplay fragment =
new ContactsSelectionListDisplay(R.layout.activity_check_in_new, context);
Bundle args = new Bundle();
//args.putString(ARG_PARAM1, param1);
//args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
Log.i(TAG, "ContactsSelectionListDisplay newInstance: ");
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "ContactsSelectionListDisplay onCreate: ");
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
viewModelFactory = new MainViewModelProviderFactory(this.context);
mViewModel = new ViewModelProvider(this, viewModelFactory).get(MainViewModel.class);
Log.i(TAG, "ContactsSelectionListDisplay onCreateView: ");
mAdapter = new CheckInContactsSelectionListDisplayAdapter(R.layout.fragment_contacts_selection_list_display, context);
RecyclerView recyclerView = getActivity().findViewById(R.id.check_in_recipient_selection_list_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(mAdapter);
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
LinearLayoutManager.VERTICAL));
return inflater.inflate(R.layout.fragment_contacts_selection_list_display, container, false);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
Log.i(TAG, "ContactsSelectionListDisplay : OnAttach");
viewModelFactory = new MainViewModelProviderFactory(context.getApplicationContext());
mViewModel = new ViewModelProvider(this, viewModelFactory).get(MainViewModel.class);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i(TAG, "ContactsSelectionListDisplay: On Activity Created");
context = this.getContext();
mViewModel = new ViewModelProvider(this, viewModelFactory).get(MainViewModel.class);
mAdapter = new CheckInContactsSelectionListDisplayAdapter(R.layout.fragment_contacts_selection_list_display, context);
RecyclerView recyclerView = getView().findViewById(R.id.check_in_recipient_selection_list_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(mAdapter);
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
LinearLayoutManager.VERTICAL));
observerSetup();
Log.i(TAG, "ContactsSelectionListDisplay onActivityCreated: Observer SetUp");
ItemTouchHelper.SimpleCallback callback = new
ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT) {
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();
mAdapter.deleteItem(position);
Snackbar snackbar = Snackbar.make(viewHolder.itemView, "Item " + (direction == ItemTouchHelper.RIGHT ? "deleted" : "archived") + ".", Snackbar.LENGTH_LONG);
snackbar.setDuration(3000);
snackbar.setAction(android.R.string.cancel, new View.OnClickListener() {
@Override
public void onClick(View view) {
mAdapter.undoDelete();
}
});
snackbar.show();
}
@Override
public void onChildDraw (Canvas c, RecyclerView
recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY,
int actionState, boolean isCurrentlyActive){
new RecyclerViewSwipeDecorator.Builder(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
.addSwipeLeftBackgroundColor(ContextCompat.getColor(getContext(), R.color.recycler_view_item_swipe_left_background))
.addSwipeLeftActionIcon(R.drawable.ic_archive_white_24dp)
.addSwipeRightBackgroundColor(ContextCompat.getColor(getContext(), R.color.recycler_view_item_swipe_right_background))
.addSwipeRightActionIcon(R.drawable.ic_delete_white_24dp)
.addSwipeRightLabel(getString(R.string.action_delete))
.setSwipeRightLabelColor(Color.WHITE)
.addSwipeLeftLabel(getString(R.string.action_archive))
.setSwipeLeftLabelColor(Color.WHITE)
.create()
.decorate();
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recyclerView);
CustomToast newtoast = new CustomToast(getContext(),"you clicked on this" );
newtoast.show();
}
@Override
public void onDetach() {
super.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 observerSetup() {
Log.i(TAG, "ContactsSelectionListDisplay observerSetup:");
checkInContactsPhotoThumbnail = getView().findViewById(R.id.checkInRecipientSelectedPhotoThumbnail);
checkInContactsDisplayLastName = getView().findViewById(R.id.checkInRecipientSelectedLastName);
checkInContactsDisplayFirstName = getView().findViewById(R.id.checkInRecipientSelectedFirstName);
checkInContactsListGroups = getView().findViewById(R.id.checkInRecipientSelectedGroups);
if(mViewModel.getSelectionListContacts() != null)
Log.i(TAG, "ContactsSelectionListDisplay getSelectionListContacts != null observerSetup: ");
Objects.requireNonNull(mViewModel.getSelectionListContacts()).observe(getViewLifecycleOwner(),
new Observer<List<ContactTable>>() {
@Override
public void onChanged(@Nullable final List<ContactTable> allSelectionListContacts) {
Log.i(TAG, "ContactsSelectionListDisplay observer setup onChanged: ");
mAdapter.setContactList(allSelectionListContacts);
}
});
}
}
The following is the recycler adapter for the first child fragment (ContactListSelectionAndDisplayAdapter)
public class CheckInContactsSelectionListDisplayAdapter extends
RecyclerView.Adapter<CheckInContactsSelectionListDisplayAdapter.ViewHolder> {
private int contactSelectionListLayout;
private List<ContactTable> contactSelectionList;
private List<ContactTable> foundContact;
private List<ContactTable> foundContactByContract;
private CoordinatorLayout coordinatorLayout;
private RecyclerView recyclerView;
private ContactTable mRecentlyDeletedItem;
private ContactTable mContactToDelete;
private ContactTableDao contactTableDao;
private ContactTableRepository contactTableRepository;
private int mContactTablePrimaryKey;
private int mContactPrimaryKey;
private int mCheckInRecipientsTablePrimaryKey;
private String mContactLastName;
private int mRecentlyDeletedItemPosition;
private Context context;
private MainViewModel mViewModel;
private MainViewModelProviderFactory viewModelFactory;
//private ArrayList recipientsToDelete = new ArrayList(20);
private int indexPosition;
private int index;
private int numberOfRecipientsToDelete;
private List<Integer> tableOfContactsToDelete;
private List<Integer> contactsToDelete;
private List<ContactTable> contactsToInsert ;
private ContactTable mContactsTableRecord;
private MyFirebaseMessagingService myFirebaseMessagingService;
public CheckInContactsSelectionListDisplayAdapter(int layoutId, Context context) {
Log.i(TAG, "CheckInContactsSelectionListDisplayAdapter: ");
contactSelectionListLayout = layoutId;
this.context = context;
}
public void setContactList(List<ContactTable> allSelectionListContacts) {
contactSelectionList = allSelectionListContacts;
Log.i(TAG, "ContactsSelectionListDisplayAdapter setContactList: ");
notifyDataSetChanged();
}
public void deleteItem(int position) {
Log.i(TAG, "ContactsSelectionListDisplayAdapter deleteItem: ");
indexPosition = 0;
mRecentlyDeletedItem = contactSelectionList.get(position);
mRecentlyDeletedItemPosition = position;
mContactTablePrimaryKey = contactSelectionList.get(position).getContactTablePrimaryKey();
mContactPrimaryKey = mContactTablePrimaryKey;
mContactLastName = contactSelectionList.get(position).getContactLastName();
viewModelFactory = new MainViewModelProviderFactory(context.getApplicationContext());
mViewModel = new MainViewModel(context.getApplicationContext());
contactSelectionList.remove(position);
notifyItemRemoved(position);
}
public void undoDelete() {
Log.i(TAG, "ContactsSelectionListDisplayAdapter undoDelete: ");
contactSelectionList.add(mRecentlyDeletedItemPosition,
mRecentlyDeletedItem);
notifyItemInserted(mRecentlyDeletedItemPosition);
//reinsert of record from Contact delete
mViewModel.insertContact(mRecentlyDeletedItem);
//reinsert CheckInRecipientsTable records from CheckIn associated delete
//undoDeleteRecipientsForCheckIn();
}
@Override
public int getItemCount() {
Log.i(TAG, "ContactsSelectionListDisplayAdapter getItemCount: ");
if (contactSelectionList == null)
return 0;
else
return contactSelectionList.size();
//return contactSelectionList == null ? 0 : contactSelectionList.size();
}
@Override
public CheckInContactsSelectionListDisplayAdapter.ViewHolder
onCreateViewHolder(ViewGroup parent, int viewType) {
Log.i(TAG, "ContactsSelectionListDisplayAdapter onCreateViewHolder: ");
View view = LayoutInflater.from(
parent.getContext()).inflate(R.layout.recycler_view_check_in_contacts_list, parent, false);
CheckInContactsSelectionListDisplayAdapter.ViewHolder checkInContactListViewHolder = new CheckInContactsSelectionListDisplayAdapter.ViewHolder(view);
return checkInContactListViewHolder;
}
@Override
public void onBindViewHolder(final CheckInContactsSelectionListDisplayAdapter.ViewHolder holder, final int listPosition) {
TextView contactTablePrimaryKey = holder.contactTablePrimaryKey;
TextView contactLastName = holder.contactLastName;
TextView contactFirstName = holder.contactFirstName;
Log.i(TAG, "ContactsSelectionListDisplayAdapter onBindViewHolder: ");
contactTablePrimaryKey.setText(contactSelectionList.get(listPosition).getContactTablePrimaryKey());
contactLastName.setText(contactSelectionList.get(listPosition).getContactLastName());
contactFirstName.setText(contactSelectionList.get(listPosition).getContactFirstName());
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView contactTablePrimaryKey;
TextView contactLastName;
TextView contactFirstName;
TextView contactThumbnailPhoto;
TextView contactGroupsList;
Button contactSelectedButton;
ViewHolder(View itemView) {
super(itemView);
Log.i(TAG, "ContactsSelectionListDisplayAdapter ViewHolder: ");
contactTablePrimaryKey = itemView.findViewById(R.id.checkInTablePrimaryKey);
contactLastName = itemView.findViewById(R.id.checkInContactsDisplayLastName);
contactFirstName = itemView.findViewById(R.id.checkInContactsDisplayFirstName);
contactThumbnailPhoto = itemView.findViewById(R.id.checkInContactsListPhotoThumbnail);
}
}
}