Проблемы с реализацией режима контекстного действия в фрагменте recyclerview

Я взломал свое первое приложение из кучи учебников. С помощью одного из них я реализовал RecyclerView внутри фрагмента, который используется основным действием. Теперь я нашел еще один учебник, который я хочу использовать для реализации множественного выбора в режиме контекстного действия. Большая проблема заключается в том, что в учебнике не используется фрагмент. Я попытался переписать код, чтобы он поместился в фрагмент. Я сейчас в точке, где я не получаю никаких ошибок в Android Studio и приложение работает, но когда я на самом деле делаю LongClick, чтобы выбрать элемент, он выходит из строя с помощью NullPointerException:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.view.ActionMode.setTitle(java.lang.CharSequence)' on a null object reference

Я полностью потерял мнение о том, почему это происходит и с целым мульти-отборным материалом в целом.

Я думаю, что соответствующие части каждого участвующего класса:

Adapter.java:

 public class Adapter extends SelectableAdapter<Adapter.ViewHolder> { private ArrayList<Meal> items = new ArrayList<>(); private Context context; private ViewHolder.ClickListener clickListener; public Adapter(ViewHolder.ClickListener clickListener) { super(); this.clickListener = clickListener; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_today_items, parent, false); return new ViewHolder(v, clickListener); } @Override public void onBindViewHolder(final ViewHolder holder, int position) { Meal currentMeal = items.get(position); holder.meal_typeicon.setImageResource(currentMeal.getBadgeIcon()); holder.meal_price.setText(currentMeal.getPriceOutput()); holder.meal_name.setText(isSelected(position) ? "SELECTED" : "NOT SELECTED"); } public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { @SuppressWarnings("unused") private static final String TAG = ViewHolder.class.getSimpleName(); private RelativeLayout meal_item; private ClickListener listener; private TextView meal_name; private TextView meal_price; private TextView meal_contents; private TextView meal_contents_spelledout; private ImageView meal_typeicon; public ViewHolder(View itemView, ClickListener listener) { super(itemView); meal_item = (RelativeLayout) itemView.findViewById(R.id.meal_item); this.listener = listener; itemView.setOnClickListener(this); itemView.setOnLongClickListener(this); meal_name = (TextView) itemView.findViewById(R.id.meal_name); meal_price = (TextView) itemView.findViewById(R.id.meal_price); meal_contents = (TextView) itemView.findViewById(R.id.meal_contents); meal_contents_spelledout = (TextView) itemView.findViewById(R.id.meal_contents_spelledout); meal_typeicon = (ImageView) itemView.findViewById(R.id.meal_typeicon); } @Override public void onClick(View v) { if (listener != null) { listener.onItemClicked(getAdapterPosition()); } } @Override public boolean onLongClick(View v) { if (listener != null) { return listener.onItemLongClicked(getAdapterPosition()); } return false; } public interface ClickListener { void onItemClicked(int position); boolean onItemLongClicked(int position); } } @Override public int getItemCount() { return items.size(); } public void setMealList(ArrayList<Meal> listMeals) { this.items = listMeals; notifyDataSetChanged(); notifyItemRangeChanged(0, listMeals.size()); } } 

SelectableAdapter.java:

 public abstract class SelectableAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> { @SuppressWarnings("unused") private static final String TAG = SelectableAdapter.class.getSimpleName(); private SparseBooleanArray selectedItems; public SelectableAdapter() { selectedItems = new SparseBooleanArray(); } /** * Indicates if the item at position position is selected * @param position Position of the item to check * @return true if the item is selected, false otherwise */ public boolean isSelected(int position) { return getSelectedItems().contains(position); } /** * Toggle the selection status of the item at a given position * @param position Position of the item to toggle the selection status for */ public void toggleSelection(int position) { if (selectedItems.get(position, false)) { selectedItems.delete(position); } else { selectedItems.put(position, true); } notifyItemChanged(position); } /** * Clear the selection status for all items */ public void clearSelection() { List<Integer> selection = getSelectedItems(); selectedItems.clear(); for (Integer i : selection) { notifyItemChanged(i); } } /** * Count the selected items * @return Selected items count */ public int getSelectedItemCount() { return selectedItems.size(); } /** * Indicates the list of selected items * @return List of selected items ids */ public List<Integer> getSelectedItems() { List<Integer> items = new ArrayList<>(selectedItems.size()); for (int i = 0; i < selectedItems.size(); ++i) { items.add(selectedItems.keyAt(i)); } return items; } } 

FragmentToday.java:

 public class FragmentToday extends Fragment implements Adapter.ViewHolder.ClickListener{ private RequestQueue requestQueue; public ArrayList<Meal> listMeals = new ArrayList<>(); private TextView textVolleyError; private MealSorter mSorter = new MealSorter(); private Adapter adapter; private ActionModeCallback actionModeCallback = new ActionModeCallback(); private ActionMode actionMode; public static FragmentToday newInstance() { return new FragmentToday(); } public FragmentToday() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); VolleySingleton volleySingleton = VolleySingleton.getInstance(); requestQueue = volleySingleton.getRequestQueue(); sendJsonRequest(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_today, container, false); textVolleyError = (TextView) view.findViewById(R.id.textVolleyError); adapter = new Adapter(this); RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); recyclerView.setAdapter(adapter); recyclerView.setItemAnimator(new DefaultItemAnimator()); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); sendJsonRequest(); return view; } @Override public void onItemClicked(int position) { if (actionMode != null) { toggleSelection(position); } } @Override public boolean onItemLongClicked(int position) { if (actionMode != null) { ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback); } toggleSelection(position); return true; } private void toggleSelection(int position) { adapter.toggleSelection(position); int count = adapter.getSelectedItemCount(); if (count == 0) { actionMode.finish(); } else { actionMode.setTitle(String.valueOf(count)); actionMode.invalidate(); } } private class ActionModeCallback implements ActionMode.Callback { @SuppressWarnings("unused") private final String TAG = ActionModeCallback.class.getSimpleName(); @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { mode.getMenuInflater().inflate (R.menu.menu_cam, menu); return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.favorite: // TODO: actually remove items Log.d(TAG, "menu_remove"); mode.finish(); return true; default: return false; } } @Override public void onDestroyActionMode(ActionMode mode) { adapter.clearSelection(); actionMode = null; } } } 

Solutions Collecting From Web of "Проблемы с реализацией режима контекстного действия в фрагменте recyclerview"

Проблема, похоже, onItemLongClicked с вашим методом onItemLongClicked класса FragmentToday.java . Это должно было быть:

 @Override public boolean onItemLongClicked(int position) { if (actionMode == null) { actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback); } toggleSelection(position); return true; } 

вместо:

 @Override public boolean onItemLongClicked(int position) { if (actionMode != null) { ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback); } toggleSelection(position); return true; }