Home > Software design >  Recycler View : Attempt to invoke virtual method on a null object reference
Recycler View : Attempt to invoke virtual method on a null object reference

Time:06-10

I've been trying to figure out this problem but I am new to Android Studio, when I try to run the app it displays this message:

Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setAdapter(androidx.recyclerview.widget.RecyclerView$Adapter)' on a null object reference

Here's my Main Activity file which is the cause :

package com.sti.lazshop;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;

import com.sti.lazshop.databinding.ActivityMainBinding;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    ActivityMainBinding binding;
    ArrayList<ItemModel> itemModels = new ArrayList<>();
    int[] itemImages = {R.drawable.item_huion, R.drawable.item_iphone};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        RecyclerView recyclerView = findViewById(R.id.mRecyclerView);
        Item_RecyclerViewAdapter adapter = new Item_RecyclerViewAdapter(this, itemModels);
        setItemModels();
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        replaceFragment(new HomeFragment());

        binding.bottomNavigationView2.setOnItemSelectedListener(item -> {

            switch (item.getItemId()) {
                case R.id.home:
                    replaceFragment(new HomeFragment());
                    break;
                case R.id.cart:
                    replaceFragment(new CartFragment());
                    break;
                case R.id.account:
                    replaceFragment(new AccountFragment());
                    break;

            }
            return true;
        });

    }

    private void replaceFragment(Fragment fragment) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.frameLayout, fragment);
        fragmentTransaction.commit();

    }

    private void setItemModels() {
        String[] itemNames = getResources().getStringArray(R.array.item_full_txt);
        String[] itemPrices = getResources().getStringArray(R.array.item_prices);

        for (int i = 0; i < itemNames.length; i  ) {
            itemModels.add(new ItemModel(
                    itemNames[i],
                    itemPrices[i],
                    itemImages[i]));
        }

    }

}

Here's the HomeFragment.java :

package com.sti.lazshop;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class HomeFragment extends Fragment {

    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    private String mParam1;
    private String mParam2;

    public HomeFragment() {
    }

    public static HomeFragment newInstance(String param1, String param2) {
        HomeFragment fragment = new HomeFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

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

        return inflater.inflate(R.layout.fragment_home, container, false);
    }
}

Lastly, the fragment_home.xml :

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".HomeFragment">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@ id/mRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>

There's a similar question to this but I don't know how to apply it and can't find a solution at the moment. I used a bottom navigator to navigate between fragments where fragment_home.xml recycler view is included. Thank you!

CodePudding user response:

As I understand from fragment_home.xml You have a RecyclerView inside of HomeFragment xml layout. But you are tryin to find the View inside MainActivity. The issue in your MainActivity's onCreate method. When you call :

RecyclerView recyclerView = findViewById(R.id.mRecyclerView);

From MainActivity It's trying to find a View with id: R.id.mRecyclerView in you activity_main.xml(xml layout that you're using for MainActivity). But as I understand it's absent there, because it's inside fragment_home.xml. Your can read how find View::findViewById works here:

https://developer.android.com/reference/android/view/View#findViewById(int)

Finds the first descendant view with the given ID, the view itself if the ID matches getId(), or null if the ID is invalid (< 0) or there is no matching view in the hierarchy.

So, When it can't find the view by id, it returns null.

Then you try to set Adapter to RecyclerView's variable which actually is null.

recyclerView.setAdapter(adapter); //recyclerView is null here

That's the reason of your issue.

You have 2 options.

  1. Move RecyclerView from fragment_home.xml to activity_main.xml, than it will be worked.
  2. Another option more suitable in my opinion, since you've already used fragments:

Move your code related to RecyclerView handling to HomeFragment class and call findViewById inside HomeFragment.

  • Related