Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 869
Saira Nawaz Avatar asked Jan 27 '17 13:01

Saira Nawaz


People also ask

What is the use of ViewHolder in RecyclerView android?

A ViewHolder describes an item view and metadata about its place within the RecyclerView. Adapter implementations should subclass ViewHolder and add fields for caching potentially expensive findViewById results.

What is ViewHolder pattern in android?

ViewHolder design pattern is used to speed up rendering of your ListView - actually to make it work smoothly, findViewById is quite expensive (it does DOM parsing) when used each time a list item is rendered, it must traverse your layout hierarchy and also instantiate objects.


2 Answers

This may happen if your onCreateViewHolder method returns null

like image 120
snersesyan Avatar answered Sep 18 '22 19:09

snersesyan


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;
    }
} 
like image 42
user2657378 Avatar answered Sep 17 '22 19:09

user2657378