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.
- Move
RecyclerView
fromfragment_home.xml
toactivity_main.xml
, than it will be worked. - 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
.