Attempt to read from field 'android.view.View android.support.v7.widget.RecyclerView$ViewHolder.itemView'
Asked Answered
M

4

8

I am trying to select recyclerview item randomly with delay.I need to start random selection method after fragment load without any user interaction,But getting the following error. Afterward I put it on ImageView click to check but again I am getting same exception.Will anybody here tell me where I am making a mistake,or what else could be better way to achieve this.Below is my code

    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 start I put

selectRandomly()

at

onResume()

method and I was getting an exception:

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)

According to fragment lifecycle at Fragment LifeCycle onResume() and onStart() methods are called after view has been created. I tried putting my method there too, But no success.

Mclain answered 27/1, 2017 at 13:47 Comment(0)
L
29

This may happen if your onCreateViewHolder method returns null

Lemberg answered 10/11, 2018 at 13:56 Comment(2)
Such a simple mistake but somewhat hard to track down because the stack gives no indication of where the null pointer exception occurred. Thanks!Gorizia
@pradiptilala Yes, the onCreateViewHolder was returning null. I don't remember the specifics but this did solve the problem for me.Gorizia
T
4

It is possible that view still not loaded, which is why it is returning null exception.

This function might be useful to call when fragment is loaded and visible to the user:

// 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;
    }
} 
Tabathatabb answered 27/1, 2017 at 13:56 Comment(1)
I am calling my fragement using FragmentTransaction , as far I have read about setUserVisibleHint(boolean isVisibleToUser) method , it is affective in case of viewpager.Mclain
D
4

This problem happened to me too, in my case it happened because onCreateViewHolder returned null.

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

Changed this to something like:

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;
}
Dripping answered 5/9, 2019 at 13:36 Comment(0)
D
-1

Set this in your onCreateView() method

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

grid_attack.setLayoutManager(layoutManager);
Denticulate answered 25/2, 2020 at 13:33 Comment(1)
A null returned from onCreateViewHolder can only cause this problem. Better make sure that it is returning a ViewHolder, maybe check getViewType in case you are using mutiple ViewHolders for one RecyclerView.Grishilda

© 2022 - 2024 — McMap. All rights reserved.