Попытка чтения из поля «android.view.View android.support.v7.widget.RecyclerView$ViewHolder.itemView»

Я пытаюсь выбрать элемент recyclerview случайным образом с задержкой. Мне нужно запустить метод случайного выбора после загрузки фрагмента без какого-либо взаимодействия с пользователем, но получаю следующую ошибку. После этого я помещаю его в ImageView, щелкаю, чтобы проверить, но снова получаю то же исключение. Кто-нибудь здесь скажет мне, где я делаю ошибку, или что еще может быть лучшим способом добиться этого. Ниже приведен мой код

    package com.apponative.bjja.fragments;

import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.apponative.bjja.R;
import com.apponative.bjja.adapters.AttackGridAdapter;

import java.util.Random;

public class Fragment_AttackGrid extends Fragment {

    View v;
    RecyclerView grid_attack;
    AttackGridAdapter attackGridAdapter;
    Bundle b;
    int itemCount;
    Handler randomHandler;
    Runnable randomRunnable;
    Random rand;
    int randomNum = 0;
    long emptyTime;

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

        v = inflater.inflate(R.layout.fragment_attack_grid, container, false);

        setUpViews();

        return v;
    }

    void setUpViews() {

        b = getArguments();
        itemCount = b.getInt(getString(R.string.item_count));
        rand = new Random();
        randomHandler = new Handler();

        grid_attack = (RecyclerView) v.findViewById(R.id.attack_grid);
        RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), 4);

        grid_attack.setLayoutManager(layoutManager);
        attackGridAdapter = new AttackGridAdapter(getActivity(), itemCount);
        grid_attack.setAdapter(attackGridAdapter);

        v.findViewById(R.id.belt_black).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                selectRandomly();
            }
        });
    }

    void selectRandomly() {

        for (int i = 0; i < itemCount; i++) {
            emptyTime = emptyTime+1000;
            randomRunnable = new Runnable() {
                @Override
                public void run() {
                    grid_attack.findViewHolderForAdapterPosition(randomNum).itemView.setSelected(false);
                    randomNum = rand.nextInt((itemCount - 0) + 1) + 0;
                    grid_attack.findViewHolderForAdapterPosition(randomNum).itemView.setSelected(true);
                }
            };
            randomHandler.postDelayed(randomRunnable, emptyTime);

        }
        emptyTime = emptyTime+2000;
        randomRunnable = new Runnable() {
            @Override
            public void run() {
                grid_attack.findViewHolderForAdapterPosition(randomNum).itemView.performClick();
            }
        };
        randomHandler.postDelayed(randomRunnable, emptyTime);
    }

    @Override
    public void onResume() {
        super.onResume();
        //   selectRandomly();
    }
}

В начале ставлю

выбратьслучайно()

at

onResume()

метод, и я получил исключение:

01-27 18:28:44.969 19041-19041/com.apponative.bjja E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.apponative.bjja, PID: 19041
java.lang.NullPointerException: Attempt to read from field 'android.view.View android.support.v7.widget.RecyclerView$ViewHolder.itemView' on a null object reference                                                                                      at com.apponative.bjja.fragments.Fragment_AttackGrid$2.run(Fragment_AttackGrid.java:77)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:155)
    at android.app.ActivityThread.main(ActivityThread.java:5696)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)

В соответствии с жизненным циклом фрагмента в Fragment LifeCycle вызываются методы onResume() и onStart() после создания представления. Я тоже пытался поместить туда свой метод, но безуспешно.


person Saira Nawaz    schedule 27.01.2017    source источник


Ответы (4)


Это может произойти, если ваш метод onCreateViewHolder возвращает значение null.

person snersesyan    schedule 10.11.2018
comment
Такая простая ошибка, но ее довольно трудно отследить, потому что стек не указывает, где произошло исключение нулевого указателя. Спасибо! - person frillybob; 25.12.2018
comment
@pradiptilala Да, onCreateViewHolder возвращал null. Я не помню специфики, но это решило проблему для меня. - person frillybob; 06.02.2019

Возможно, представление еще не загружено, поэтому оно возвращает нулевое исключение.

Эту функцию может быть полезно вызывать, когда фрагмент загружен и виден пользователю:

// create boolean for checking if view is seen
private boolean isViewShown = false;

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (getView() != null) {
        isViewShown = true;
        // call your function
    } else {
        isViewShown = false;
    }
} 
person user2657378    schedule 27.01.2017
comment
Я вызываю свой фрагмент с помощью FragmentTransaction , насколько я читал о методе setUserVisibleHint(boolean isVisibleToUser) , он эффективен в случае просмотра пейджера. - person Saira Nawaz; 27.01.2017

Эта проблема возникла и у меня, в моем случае это произошло из-за того, что onCreateViewHolder вернул null.

public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    return null;
}

Изменил это на что-то вроде:

public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext())
                              .inflate(R.layout.category_recylcer_view, parent, false);
    ViewHolder holder = new ViewHolder(view);
    return holder;
}
person Achintha Isuru    schedule 05.09.2019

Установите это в своем методе onCreateView()

grid_attack = (RecyclerView) v.findViewById(R.id.attack_grid);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), 4);

grid_attack.setLayoutManager(layoutManager);
person Jyotiprakash Das    schedule 25.02.2020