Android: обновление пункта меню программным способом приводит к NullPointerException

Я работаю над RecylcerView а также CardView, Карты содержат ImageView. У меня также есть пункт меню, который объявлен как действие и заголовок которого установлен на 0. Чего я хочу добиться, так это того, чтобы при нажатии на изображение его позиция добавлялась в массив, а заголовок пункта меню быть размером массива.

Ниже приведен код my menu.xml:

<menu 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" 
    tools:context=".MainActivity">

    ...

    <item 
      android:id="@+id/action_down_list" 
      android:title="@string/action_down_list"
      android:orderInCategory="100" 
      app:showAsAction="withText|always" 
      android:icon="@drawable/ic_action_download" />
</menu>

Ниже приведен код класса адаптера, из которого я запускаю onClickListner код:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
    List<String> abc = new ArrayList<String>();
    ...      
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        ...
        viewHolder.imgView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                String img_id = images.get(viewHolder.getAdapterPosition());
                MenuItem dl_menu = (MenuItem) view.findViewById(R.id.action_down_list);

                abc.add(img_id);
                dl_menu.setTitle(Integer.toString(abc.size()));

                return true;
            }
        });
    }
}

Но когда я запускаю свою программу, это дает java.lang.NullPointerException, У меня есть разные методы, но до сих пор нет решения.

1 ответ

Решение

Проблема в этой линии.

MenuItem dl_menu = (MenuItem) view.findViewById(R.id.action_down_list);

Вы попытались найти пункт меню, в котором его нет. Нет простого способа получить доступ к меню из адаптера.

Самый простой способ в вашей ситуации - создать в вашем адаптере набор методов для меню,

public void setMenu(Menu menu){
   this.menu = menu;
}

и вызовите его для вашего адаптера в onCreateOptionsMenu Обратный вызов, убедитесь, что ваш адаптер инициализирован до него. После этого вы можете написать:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
   List<String> abc = new ArrayList<String>();
   Menu menu;
   ...      
   @Override
   public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
     ...
     viewHolder.imgView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                String img_id = images.get(viewHolder.getAdapterPosition());
                MenuItem dl_menu = menu.findItem(R.id.action_down_list);

                abc.add(img_id);
                dl_menu.setTitle(Integer.toString(abc.size()));

                return true;
            }
        });

Но предпочтительный способ с моей точки зрения - использовать что-то вроде LocalBroadcastManager для отправки в Activity или Fragment намерение с информацией о том, что следует делать с элементом меню. Таким образом, адаптер не будет иметь прямого доступа к меню.

Другие вопросы по тегам