Arhn - архитектура программирования

Поля ViewHolder инициализируются как пустые во фрагменте

Я пытаюсь настроить gridLayout в представлении ресайклера, используя несколько макетов xml grid_cell, каждый из которых содержит 5 ImageView. У меня recyclerView работал нормально, пока я не реструктурировал код для размещения базы данных.

Проблема в том, что все ImageView инициализируются как null в конструкторе MapViewHolder, что приводит к java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageView.setImageResource(int) в ссылке на нулевой объект "

public class MapFragment extends Fragment
{
    private GameDataStorage gameDataStorage;
    private RecyclerView rv;
    private MapAdapter adapter;
    private GridLayoutManager gridLayoutManager;

    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        gameDataStorage = ((SubApplication)getActivity().getApplication()).gameDataStorage;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle bundle)
    {
        //Inflate the view from fragment_map.xml layout.
        View view = inflater.inflate(R.layout.fragment_map, parent, false);

        //Crate the recycler view from the map_recycler_view.xml layout
        rv = view.findViewById(R.id.map_recycler_view);

        adapter = new MapAdapter();

        //Initialise the grid layout manager
        gridLayoutManager = new GridLayoutManager(getActivity(), GameData.getInstance().getSettings().getMapHeight(), GridLayoutManager.HORIZONTAL, false);

        //Set the recycler view adapter
        rv.setAdapter(adapter);

        //Set the layout manager to be a horizontal scrolling grid
        rv.setLayoutManager(gridLayoutManager);

        return view;
    }

    public class MapViewHolder extends RecyclerView.ViewHolder
    {
        private ImageView structure;
        private ImageView topLeft;
        private ImageView topRight;
        private ImageView bottomLeft;
        private ImageView bottomRight;

        public MapViewHolder(LayoutInflater li, ViewGroup parent)
        {
            super(li.inflate(R.layout.grid_cell, parent, false));

            int size = parent.getMeasuredHeight() / GameData.getInstance().getSettings().getMapHeight() + 1;
            ViewGroup.LayoutParams lp = parent.getLayoutParams();
            lp.height = size;
            lp.width = size;

            structure = (ImageView) parent.findViewById(R.id.structure);
            topLeft = (ImageView) parent.findViewById(R.id.top_left);
            topRight = (ImageView) parent.findViewById(R.id.top_right);
            bottomLeft = (ImageView) parent.findViewById(R.id.bottom_left);
            bottomRight = (ImageView) parent.findViewById(R.id.bottom_right);

            //DEBUGGING
            Log.d("GAME_DATA", "structure reference is initialised as " + structure);
            Log.d("GAME_DATA", "topLeft reference is initialised as " + topLeft);
            Log.d("GAME_DATA", "topRight reference is initialised as " + topRight);
            Log.d("GAME_DATA", "bottomLeft reference is initialised as " + bottomLeft);
            Log.d("GAME_DATA", "bottomRight reference is initialised as " + bottomRight);
        }

        public void bind(final MapElement element, final int index)
        {
            if(element.getStructure() != null){
                structure.setImageResource(element.getStructure().getImageId());
            }
            else
            {
                if(structure == null)
                {
                    Log.d("GAME_DATA", "structure reference is null for mapElement " + index);
                }

                structure.setImageResource(GameData.getInstance().getEmpty());
            }
            topLeft.setImageResource(element.getTopLeft());
            topRight.setImageResource(element.getTopRight());
            bottomLeft.setImageResource(element.getBottomLeft());
            bottomRight.setImageResource(element.getBottomRight());

            structure.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v)
                {
                    int row = index % GameData.getInstance().getSettings().getMapHeight();
                    int col = index / GameData.getInstance().getSettings().getMapHeight();
                    StructureData.setStructureAt(row, col);

                    gameDataStorage.updateMapElement(element, element.getStructure(), index);

                    adapter.notifyItemChanged(index);
                }
            });

            structure.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    return false;
                }
            });
        }
    }
    // END_INCLUDE(recyclerViewSampleViewHolder)

    public class MapAdapter extends RecyclerView.Adapter<MapViewHolder>
    {
        // BEGIN_INCLUDE(recyclerViewOnCreateViewHolder)
        // Create new views (invoked by the layout manager)
        @Override
        public MapViewHolder onCreateViewHolder(ViewGroup container, int viewType)
        {
            Log.d("GAME_DATA", "new MapViewHolder using ViewGroup " + container + " and viewType " + viewType);
            return new MapViewHolder(LayoutInflater.from(getActivity()), container);
        }
        // END_INCLUDE(recyclerViewOnCreateViewHolder)

        // BEGIN_INCLUDE(recyclerViewOnBindViewHolder)
        // Replace the contents of a view (invoked by the layout manager)
        @Override
        public void onBindViewHolder(MapViewHolder vh, int index) {
            // Get element from your dataset at this position and replace the contents of the view
            // with that element
            int row = index % GameData.getInstance().getSettings().getMapHeight();
            int col = index / GameData.getInstance().getSettings().getMapHeight();
            MapElement element = GameData.getInstance().getMapLoc(row, col);

            vh.bind(element, index);
        }
        // END_INCLUDE(recyclerViewOnBindViewHolder)



        // Return the size of your dataset (invoked by the layout manager)
        @Override
        public int getItemCount() {
            int rows = GameData.getInstance().getMap().length;
            int cols = GameData.getInstance().getMap()[0].length;
            int length = rows * cols;
            Log.d("GAME_DATA", "getItemCount returns: " + length);
            return length;
        }
    }
}

Выход Logcat:

10-22 19: 31: 59.177 19926-19926 / com.example.mad_assignment_rebuild D / GAME_DATA: новый MapViewHolder с использованием ViewGroup androidx.recyclerview.widget.RecyclerView {353fb6f6 VFED .... ...... ID 0,0- 1080,1188 # 7f07005e app: id / map_recycler_view} и viewType 0 10-22 19: 31: 59.187 19926-19926 / com.example.mad_assignment_rebuild D / GAME_DATA: ссылка на структуру инициализируется как пустая 10-22 19: 31: 59.187 19926 -19926 / com.example.mad_assignment_rebuild D / GAME_DATA: ссылка topLeft инициализируется как null 10-22 19: 31: 59.187 19926-19926 / com.example.mad_assignment_rebuild D / GAME_DATA: ссылка topRight инициализируется как null 10-22 19: 31: 59.187 19926-19926 / com.example.mad_assignment_rebuild D / GAME_DATA: ссылка bottomLeft инициализируется как null 10-22 19: 31: 59.187 19926-19926 / com.example.mad_assignment_rebuild D / GAME_DATA: bottomRight инициализируется как null 10 -22 19: 31: 59.187 19926-19926 / com.example.mad_assignment_rebuild D / GAME_DATA: ссылка на структуру для mapElement 0 пуста

Вывод ошибки отладки:

E / AndroidRuntime: FATAL EXCEPTION: main Process: com.example.mad_assignment_rebuild, PID: 19926 java.lang.NullPointerException: попытка вызвать виртуальный метод void android.widget.ImageView.setImageResource (int) для ссылки на нулевой объект в com .example.mad_assignment_rebuild.MapRecyclerFiles.MapFragment $ MapViewHolder.bind (MapFragment.java:101) по адресу com.example.mad_assignment_rebuild.MapRecyclerFiles.MapFragment $ MapAdapter.onBindViewHolcycler.MapFragment $ MapAdapter. $ MapAdapter.onBindViewHolder (MapFragment.java:132)


Ответы:


1

Я думаю, проблема в том, что вы хотели узнать свои взгляды из parent просмотра. Вы должны найти свое представление из своего item layout представления (в данном случае R.layout.grid_cell).

Попробуйте вот так.

public MapViewHolder(LayoutInflater li, ViewGroup parent)
    {
        final View = li.inflate(R.layout.grid_cell, parent, false);
        super(view);

        int size = view.getMeasuredHeight() / GameData.getInstance().getSettings().getMapHeight() + 1;
        ViewGroup.LayoutParams lp = view.getLayoutParams();
        lp.height = size;
        lp.width = size;

        structure = (ImageView) view.findViewById(R.id.structure);
        topLeft = (ImageView) view.findViewById(R.id.top_left);
        topRight = (ImageView) view.findViewById(R.id.top_right);
        bottomLeft = (ImageView) view.findViewById(R.id.bottom_left);
        bottomRight = (ImageView) view.findViewById(R.id.bottom_right);

        //DEBUGGING
        Log.d("GAME_DATA", "structure reference is initialised as " + structure);
        Log.d("GAME_DATA", "topLeft reference is initialised as " + topLeft);
        Log.d("GAME_DATA", "topRight reference is initialised as " + topRight);
        Log.d("GAME_DATA", "bottomLeft reference is initialised as " + bottomLeft);
        Log.d("GAME_DATA", "bottomRight reference is initialised as " + bottomRight);
    }

Или можно сделать более понятным и простым ,,, Вот так.

    public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.Holder> {
    private final List<Model> list;

    RecyclerViewAdapter(List<WorkshopObj> data, EditTextChangeWorkshopListener editTextChangeWorkshopListener) {
        list = data;

        setHasStableIds(true);
    }

    @NotNull
    @Override
    public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new Holder(LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_workshop_adapter, parent, false));
    }

    @Override
    public void onBindViewHolder(final Holder holder, final int position) {

        final WorkshopObj model = list.get(position);

        holder.titleWorkshop.setText(model.getTitleText());
        holder.requiredWorkshop.setVisibility(model.isRequired() ? View.VISIBLE : View.GONE);
        holder.subTitle.setVisibility(model.isMandatory() ? View.VISIBLE : View.GONE);

    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    class Holder extends RecyclerView.ViewHolder {

        private final TextView requiredWorkshop;
        private final TextView titleWorkshop;
        private final TextView subTitle;
        private final EditText price;

        Holder(View view) {
            super(view);
            requiredWorkshop = view.findViewById(R.id.required_workshop);
            titleWorkshop = view.findViewById(R.id.title_workshop);
            subTitle = view.findViewById(R.id.sub_title);
            price = view.findViewById(R.id.price);
        }
    }
}
22.10.2019
  • Спасибо за ответ. В конце концов, мы сделали что-то вроде первого, но создали View view перед построением и передали его в конструктор, так как super() должен быть вызван первым. 23.10.2019
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..