1

I tried to create a RecyclerView on a Fragment with a custom layout, so I used an adapter, but, when I tried to set the adapter, I got these errors:

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

I've tried some solutions on the Internet, everyone suggest to try finding the recyclerview inside the OnViewCreated. But my code still cant find the recyclerview inside the layout file.

This is my fragment_hadiah.xml File

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".HadiahFragment"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:padding="20dp"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic_video"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="x Dopa Eggs"
                android:textSize="20sp"
                android:textStyle="bold"
                android:layout_marginStart="10dp"/>
        </LinearLayout>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Tukarkan pointmu"/>
    </LinearLayout>

    <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="horizontal"
            android:paddingVertical="10dp">

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="GOPAY"
                android:layout_marginLeft="20dp"/>

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="OVO"
                android:layout_marginLeft="20dp"/>

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="DANA"
                android:layout_marginLeft="20dp"/>

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Coming Soon"
                android:layout_marginLeft="20dp"/>

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Coming Soon"
                android:layout_marginLeft="20dp"/>

        </LinearLayout>
    </HorizontalScrollView>

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

</LinearLayout>

Here is my HadiahFragment.java class

package com.dopami.projecthatchedeggs;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.dopami.projecthatchedeggs.adapter.HadiahItemAdapter;

import java.util.ArrayList;
import java.util.List;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link HadiahFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class HadiahFragment extends Fragment {

    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    private String mParam1;
    private String mParam2;

    RecyclerView hadiahRecyclerView;

    public HadiahFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment HadiahFragment.
     */
    public static HadiahFragment newInstance(String param1, String param2) {
        HadiahFragment fragment = new HadiahFragment();
        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) {
        // Inflate the layout for this fragment
        View view =  inflater.inflate(R.layout.fragment_beranda, container, false);

        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        List<String> itemList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            itemList.add(String.valueOf(i));
        }

        Toast.makeText((HomeActivity) getActivity(), "OK", Toast.LENGTH_SHORT).show();

        hadiahRecyclerView = view.findViewById(R.id.hadiahRecylerView);
        HadiahItemAdapter itemAdapter = new HadiahItemAdapter(itemList, (HomeActivity) getActivity());
        GridLayoutManager gridLayoutManager = new GridLayoutManager((HomeActivity)getActivity(), 2);
        hadiahRecyclerView.setAdapter(itemAdapter);
        hadiahRecyclerView.setLayoutManager(gridLayoutManager);
    }
}

Here is My HadiahItemAdapter.java Class

package com.dopami.projecthatchedeggs.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;

import com.dopami.projecthatchedeggs.R;

import java.util.List;

public class HadiahItemAdapter extends RecyclerView.Adapter<HadiahItemAdapter.ItemViewHolder>{

    private List<String> mItemList;
    private Context mContext;

    public HadiahItemAdapter(List<String> mItemList, Context mContext) {
        this.mItemList = mItemList;
        this.mContext = mContext;
    }

    @NonNull
    @Override
    public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.hadiah_card_item, parent, false);
        return new ItemViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
        String item = mItemList.get(position);
        holder.textView.setText(item);
    }

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

    class ItemViewHolder extends RecyclerView.ViewHolder{

        private CardView cardView;
        private TextView textView;

        public ItemViewHolder(@NonNull View itemView) {
            super(itemView);

            cardView = itemView.findViewById(R.id.hadiahCardView);
            textView = itemView.findViewById(R.id.hadiahCardTextView);
        }
    }
}

Looking forward to the solutions from you guys, thanks for helping...

Regn
  • 80
  • 1
  • 1
  • 12
  • 1
    You are inflating `R.layout.fragment_beranda` while you have `recyclerview` inside `R.layout.fragment_hadiah` .. Why is that ? – ADM Mar 29 '22 at 07:42
  • Does this answer your question? [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – cmak Mar 29 '22 at 07:55
  • Yeah, I didn't realize that I am inflating the wrong layout, now it fixed :) – Regn Mar 29 '22 at 08:00
  • @Regn why don't you use view binding? No longer doing `findViewById()`!!! – Sambhav Khandelwal Mar 31 '22 at 15:42
  • @Sambhav.K Wow, it sounds new to me, do you have references or tutorial on how to do it? Many thanks for the idea – Regn Apr 01 '22 at 04:30
  • See [this](https://youtu.be/z0F2QTAKsWU) – Sambhav Khandelwal Apr 01 '22 at 04:39

1 Answers1

3

Your fragment inflates the XML like this:

View view =  inflater.inflate(R.layout.fragment_beranda, container, false);

R.layout.fragment_beranda is not the layout you want (or shared fragment_hadiah.xml).

Therefore in onViewCreated

hadiahRecyclerView = view.findViewById(R.id.hadiahRecylerView);
HadiahItemAdapter itemAdapter = new HadiahItemAdapter(itemList, (HomeActivity) getActivity());
GridLayoutManager gridLayoutManager = new GridLayoutManager((HomeActivity)getActivity(), 2);
hadiahRecyclerView.setAdapter(itemAdapter);

hadiahRecyclerView does not exist in the XML file and so the variable hadiahRecyclerView is null

meaning

hadiahRecyclerView.setAdapter(itemAdapter);

this line crashes with NullPointerException

The stacktrace error you shared says exactly that:

java.lang.NullPointerException: Attempt to invoke virtual method

'void androidx.recyclerview.widget.RecyclerView.setAdapter(androidx.recyclerview.widget.RecyclerView$Adapter)'

on a null object reference

Sayooj
  • 766
  • 5
  • 23
Blundell
  • 75,855
  • 30
  • 208
  • 233
  • Hello Blundell, thank you for the answer, this simple typing mistakes really catch me off guard, thanks for the correction. I didn't even know that I inflate the wrong layout. This almost take me an hour to fix. Thanks a lot... :)) – Regn Mar 29 '22 at 07:49
  • 1
    No problem. When you get a null pointer exception on a variable that is the result of `findViewById` it means the XML ID can't be found, which usually means you aren't inflating the XML file that contains that ID. – Blundell Mar 29 '22 at 07:51