Null Pointer Exception in RecyclerView within Fragment with Firestore - java

I am trying to populate recyclerView with Java objects using Firestore. The RecyclerView is within a fragment. I am using a recyclerViewAdapter which extends the FirestoreRecyclerAdapter class. When I run the code, the app crashes immediately.
Here's the error.
.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setLayoutManager(androidx.recyclerview.widget.RecyclerView$LayoutManager)' on a null object reference
Here's some of the fragment Java code:
public class EventsFragment extends Fragment{
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference eventRef = db.collection("Events");
private EventRecyclerAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.events_fragment, container, false);
setUpRecyclerView();
return rootView;
}
private void setUpRecyclerView(){
Query query = eventRef.limit(8);
FirestoreRecyclerOptions<Event> options = new FirestoreRecyclerOptions.Builder<Event>()
.setQuery(query, Event.class)
.build();
adapter = new EventRecyclerAdapter(options);
RecyclerView recyclerView = (RecyclerView) getActivity().findViewById(R.id.events_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
}
}
Here's the fragment xml:
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="Upcoming Events"
app:menu="#menu/main_menu"
android:background="#android:color/white"
/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="8dp"
android:clipToPadding="false"
android:divider="#null"
android:id="#+id/events_recycler_view"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Here's the RecyclerAdapter code:
public class EventRecyclerAdapter extends FirestoreRecyclerAdapter<Event, EventRecyclerAdapter.EventHolder> {
public EventRecyclerAdapter(#NonNull FirestoreRecyclerOptions<Event> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull EventHolder holder, int position, #NonNull Event model) {
holder.textViewTitle.setText(model.getTitle());
holder.textViewDescription.setText(model.getDescription());
}
#NonNull
#Override
public EventHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.events_list_item,
parent, false);
return new EventHolder(v);
}
class EventHolder extends RecyclerView.ViewHolder {
TextView textViewTitle;
TextView textViewDescription;
public EventHolder(#NonNull View itemView) {
super(itemView);
textViewTitle = itemView.findViewById(R.id.title);
textViewDescription = itemView.findViewById(R.id.description);
}
}
}
I believe the problem lies somewhere with the RecyclerView. I've been trying to find the problem for hours now. Is there something I'm overlooking? I just need it to run.

You already noticed that recyclerView is null when you try to set the LayoutManager in setUpRecyclerView()
This happens because you are trying to "find" the RecyclerView in the Activity's View tree before the Fragment's View has actually been attached to it:
RecyclerView recyclerView = (RecyclerView) getActivity().findViewById(R.id.events_recycler_view);
The first Fragment lifecycle method where you can put this statement is onResume() (at least in my example app on an emulator running Android 9)
But you can configure the RecyclerView much earlier because you can "find" it in the Fragment's own View for example in onViewCreated():
#Override
public void onViewCreated(View view, Bundle savedInstanceState){
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.events_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(view.getContext());
// etc.
}
Please note that the view parameter in onViewCreated() represents the View which you can get everywhere in the Fragment by calling getView(). But only after onCreateView() has finished, because the purpose of this method is creating and "publishing" the Fragment's View in the first place.
Last not least, inside of onCreateView() you can "find" the RecyclerView by means of the newly inflated View:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.events_fragment, container, false);
//setUpRecyclerView();
RecyclerView recyclerView = (RecyclerView) rootView .findViewById(R.id.events_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(rootView.getContext());
// etc.
return rootView;
}
So maybe you'd best pass the root View as parameter into setUpRecyclerView() and use it as follows:
private void setUpRecyclerView(ViewGroup root){
Query query = eventRef.limit(8);
FirestoreRecyclerOptions<Event> options = new FirestoreRecyclerOptions.Builder<Event>()
.setQuery(query, Event.class)
.build();
adapter = new EventRecyclerAdapter(options);
RecyclerView recyclerView = (RecyclerView) root.findViewById(R.id.events_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(root.getContext()));
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
}

Related

Fragment with RecyclerView, no adapter attached error

I'm making a tabbed activity with different fragments and one of them contains a recyclerview with just some names at the moment. I have no idea what I've done wrong, I get a warning every time on starting the app that says no adapter attached, skipping layout. I've created and set the adapter to the recyclerview in my fragment, created an adapter with viewholder, and created a class to set the name on the recyclerview.
Here is my fragment class:
public class fragment_main extends Fragment {
View view;
private RecyclerView mainrecyclerview;
private List<MainSchedule> listStr;
public fragment_main() {}
#NonNull
#Override
public View onCreateView(LayoutInflater inflater, #NonNull ViewGroup container, #NonNull Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_main, container, false);
mainrecyclerview = (RecyclerView) view.findViewById(R.id.todayRecyclerView);
MainRecyclerViewAdapter mainAdapter = new MainRecyclerViewAdapter(getActivity(), listStr);
mainrecyclerview.setLayoutManager(new LinearLayoutManager(getActivity()));
mainrecyclerview.setAdapter(mainAdapter);
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
listStr = new ArrayList<>();
listStr.add(new MainSchedule("one"));
listStr.add(new MainSchedule("two"));
listStr.add(new MainSchedule("three"));
}
}
fragment.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".fragment_main">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/todayRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="32dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="250dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
recyclerviewadapter class:
public class MainRecyclerViewAdapter extends RecyclerView.Adapter<MainRecyclerViewAdapter.ViewHolder> {
Context mContext;
List<MainSchedule> mData;
public MainRecyclerViewAdapter(Context context, List<MainSchedule> data){
this.mContext = context;
this.mData = data;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.mainschedule_cards, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.textView.setText(mData.get(position).getName());
}
#Override
public int getItemCount() {
return mData.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.textViewClass);
}
}
}
I've tried many ways of creating the adapter and binding the layout manager to the recyclerview, but nothing seems to work and I get the same error each time.
Problem seems with onCreateView because you're supposed to return view
Replace your fragment_main with code below
public class fragment_main extends Fragment {
private RecyclerView mainrecyclerview;
private List<MainSchedule> listStr;
public fragment_main() {
}
#NonNull
#Override
public View onCreateView(LayoutInflater inflater, #NonNull ViewGroup container, #NonNull Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
listStr = new ArrayList<>();
listStr.add(new MainSchedule("one"));
listStr.add(new MainSchedule("two"));
listStr.add(new MainSchedule("three"));
mainrecyclerview = (RecyclerView) view.findViewById(R.id.todayRecyclerView);
MainRecyclerViewAdapter mainAdapter = new MainRecyclerViewAdapter(getActivity(), listStr);
mainrecyclerview.setLayoutManager(new LinearLayoutManager(getActivity()));
mainrecyclerview.setAdapter(mainAdapter);
}
}

Android studio null object reference error while changing component visibility

I'm making an app that displays the same menus for different users, each menu being a fragment, but depending on the user certain things are visible and others aren't.
However, when I try to set a component's visibility as GONE I get a null pointer exception error, I'm still testing so I'm only using a textView on the fragment xml.
I've already tried initializing both the TextView and the FragmentMenuEncomenda, the class of the fragment I'm using, objects, both inside the if clause before the onCreate() method, and after the setContentView(), like the tabLayout and viewPager.
The if clause was only to make sure the user type was correct and the code in question is as follows:
public class PaginaInicialCliente extends AppCompatActivity {
private SharedPreferences sharedpreferences;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pagina_inicial_cliente);
tabLayout = findViewById(R.id.tabLayoutCliente);
viewPager = findViewById(R.id.viewPagerCliente);
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
//fragments a adicionar
adapter.addFragment(new FragmentMenuEncomendas(), "Encomendas");
adapter.addFragment(new FragmentMenuOpcoes(), "Opções");
//inicializar o tab layout
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
sharedpreferences = getSharedPreferences("user", Context.MODE_PRIVATE);
if (sharedpreferences.getInt("tipo",0)==3) {
Log.d("USER_DEBUG","Cliente");
FragmentMenuEncomendas fragmentMenuEncomendas = new FragmentMenuEncomendas();
//THE ERROR IS HERE
fragmentMenuEncomendas.getActivity().findViewById(R.id.textViewEncomendas).setVisibility(View.GONE);
}
}
}
The FragmentMenuEncomenda class:
public class FragmentMenuEncomendas extends Fragment {
View v;
public FragmentMenuEncomendas(){
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
v = inflater.inflate(R.layout.encomendas_fragment, container, false);
return v;
}
}
The xml file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textViewEncomendas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
All the answers I've searched didn't work, I don't know if it's because I'm trying to change the visibility inside the on create method.
Because view is not created when you call the function.
public class FragmentMenuEmpresas extends Fragment {
View v;
View textView;
boolean isTextViewShow = false;
boolean isViewCreated = false;
public FragmentMenuEmpresas() {
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
v = inflater.inflate(R.layout.empresas_fragment, container, false);
textView = v.findViewById(R.id.textViewEncomendas);
return v;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (isTextViewShow) {
textView.setVisibility(View.VISIBLE);
} else {
textView.setVisibility(View.GONE);
}
isViewCreated = true;
}
void setIsTextViewShow() {
if (isViewCreated) {
textView.setVisibility(View.VISIBLE);
} else {
isTextViewShow = true;
}
}
void setIsTextViewGone() {
if (isViewCreated) {
textView.setVisibility(View.GONE);
} else {
isTextViewShow = false;
}
}
}
then you can call the setIsTextViewShow or setIsTextViewGone anytime you want
FragmentMenuEncomendas fragmentMenuEncomendas = new FragmentMenuEncomendas();
fragmentMenuEncomendas.setIsTextViewShow();//show
fragmentMenuEncomendas.setIsTextViewGone();//gone

problem with removing previous view in a fragment

i have created a fragment in android that contain 2 functions, the startview() is called at the beginning when the fragment is called, then when user click a button childfragment() is called. and at that point it should have remove the view from the startview() and then replacing it with the newview from childfragment(), and thats what i thought it would do. But instead it did not remove the old view and place the newview on top of the old view. even thought i already place mContainer.removeAllViews(); it did not remove the old view. what am i missing? please help.
here is the code
#SuppressLint("ValidFragment")
public class FragmentSideContent extends android.app.Fragment {
//private OnFragmentInteractionListener mListener;
Context context;
View view,trueview;
ListView listView;
ListAdapter listAdapter;
private LayoutInflater mInflater;
private ViewGroup mContainer;
int[] image = {1,2,3};
String[] titleText = {"one","two","three","one","two","three","one","two","three","one","two","three"};
String[] subTitleText = {"one","two","three","one","two","three","one","two","three","one","two","three"};
public FragmentSideContent(Context context) {
this.context = context;
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,#Nullable Bundle savedInstanceState) {
mInflater = inflater;
mContainer = container;
startview();
return trueview;
}
public void startview(){
view = mInflater.inflate(R.layout.fragment_sidecontent,mContainer,false);
listView = (ListView) view.findViewById(R.id.noteList);
listAdapter = new ListAdapter(context,image,titleText,subTitleText);
listView.setAdapter(listAdapter);
trueview = view;
}
public void childfragment(){
mContainer.removeAllViews();
View newview = mInflater.inflate(R.layout.fragment_sidecontent,mContainer,false);
Fragment childFragment = new FragmentList(context);
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.child_fragment_container, childFragment).commit();
mContainer.addView(newview);
mContainer.addView(trueview);
trueview = newview;
}
}
I recommend you put in your fragment layout some GroupView for do this.
fragment_layout.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
in yout Fragment.java
View view;
Framelayout fContainer;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_layout, container, false);
return startView();
}
public View startview(){
fContainer = (Framelayout) view.findViewById(R.id.container);
listView = (ListView) view.findViewById(R.id.noteList);
listAdapter = new ListAdapter(context,image,titleText,subTitleText);
listView.setAdapter(listAdapter);
return view;
}
public void childfragment(){
fContainer.removeAllViews();
Fragment childFragment = new FragmentList(context);
FragmentTransaction transaction =
getChildFragmentManager().beginTransaction();
transaction.replace(R.id.container, childFragment).commit();
}
Now in your oncreateview of the other fragment (FragmentList) put the view that you want inflate.
FragmentList.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View newview = mInflater.inflate(R.layout.fragment_sidecontent,mContainer,false);
return newview;
}

Getting a null pointer exception on a RecyclerView layout manager

Hi guys I have the following error I cannot seem to resolve.
I have
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
The code I have is slightly different than from regular examples since I am doing this in a Fragment rather than in a Activity.
This is my code.
I have an xml for the whole Fragment:
<FrameLayout 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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="mtr.MainActivityFragmentTwo">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/grades"
android:textStyle="bold"
android:textSize="40dp"
android:gravity="center_horizontal"
android:layout_gravity="center"
/>
</FrameLayout>
Then I have a content_fragment which holds the RecyclerView
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="#+id/realm_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
Then my code in my Fragments looks as follows
public class MainActivityFragmentTwo extends Fragment {
private Realm realm;
private RecyclerView recyclerView;
public MainActivityFragmentTwo() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main_activity_fragment_two, container, false);
}
#Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
realm.init(getActivity());
realm = Realm.getDefaultInstance();
recyclerView = (RecyclerView) getActivity().findViewById(R.id.realm_recycler_view);
setupRecyclerView();
}
public void setupRecyclerView() {
Log.d("Found grades", "not showing grades tho");
recyclerView.setLayoutManager(new LinearLayoutManager(this.getContext()));
recyclerView.setAdapter(new gradeRealmAdapter(this, realm.where(Grade.class).findAllAsync()));
recyclerView.setHasFixedSize(true);
}
}
the Adapter I created is
public class gradeRealmAdapter extends RealmRecyclerViewAdapter<Grade, gradeRealmAdapter.GradeViewHolder> {
private final MainActivityFragmentTwo activity;
public gradeRealmAdapter (MainActivityFragmentTwo activity, RealmResults<Grade> realmResults) {
super(activity.getActivity(), realmResults, true);
this.activity = activity;
}
#Override
public GradeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new GradeViewHolder(inflater.inflate(R.layout.gradeitem, parent, false));
}
#Override
public void onBindViewHolder(GradeViewHolder holder, int position) {
Grade grade = getData().get(position);
holder.title.setText(grade.toString());
}
class GradeViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener {
public TextView title;
public Grade grade;
public GradeViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.grade_text_view);
view.setOnLongClickListener(this);
}
public boolean onLongClick(View v) {
activity.deleteItem(grade);
return true;
}
}
}
The error comes from the Fragment class on the following line
recyclerView.setLayoutManager(new LinearLayoutManager(this.getContext()));
I can't seem to resolve this.
Can anyone see what I am doing wrong?
I have an content_fragment which holds the recyclerview
Then you need to findViewById on that layout, not the Activity's.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_activity_fragment_two, container, false);
// Don't use getActivity().findViewById
recyclerView = (RecyclerView) rootView.findViewById(R.id.realm_recycler_view);
setupRecyclerView();
return rootView;
}
Then, you also have the realm initialization backwards.
realm.init(getActivity()); // This throws an exception as well
realm = Realm.getDefaultInstance(); // It is initialized afterwards
So, fix that too within onAttach, where you are guaranteed to have some Context
#Override
public void onAttach(Context context) {
super.onAttach(context);
realm = Realm.getDefaultInstance();
realm.init(context);
}
let's try to change
recyclerView.setLayoutManager(new LinearLayoutManager(this.getContext()));
with
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
And make some update for onCreateView:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView =inflater.inflate(R.layout.fragment_main_activity_fragment_two,container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.realm_recycler_view);
setupRecyclerView();
return rootView;
}
Inflate your recycler view on onViewCreated()
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView =inflater.inflate(R.layout.fragment_main_activity_fragment_two,container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.realm_recycler_view);
setupRecyclerView();
return rootView;
}
Not in onCreate

Null object reference on LayoutManager

I am getting this error when trying to set my layoutmanager for my recyclerview. I have created a layout manager and set my recyclerview to use it. For some reason the layoumanager is null.
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.jcaseydev.popularmovies/com.jcaseydev.popularmovies.ui.ReviewsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2625)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2686)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1440)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:5969)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:801)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:691)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
at com.jcaseydev.popularmovies.ui.ReviewsFragment.onCreateView(ReviewsFragment.java:65)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2074)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1286)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:758)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1671)
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:388)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:619)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1248)
at android.app.Activity.performStart(Activity.java:6686)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2588)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2686) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1440) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:5969) 
at java.lang.reflect.Method.invoke(Native Method)
Here is the recylerview class.
public ReviewsFragment(){}
RecyclerView mRecyclerView;
RecyclerView.LayoutManager linearLayoutManager;
RecyclerView.Adapter mAdapter;
private int movieId;
private List<Reviews> movieReviews = new ArrayList<>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_review, container, false);
FetchMovieReviews fmr = new FetchMovieReviews();
// fmr.execute();
//get intent
Intent intent = getActivity().getIntent();
//key for the intent extra
String MOVIE_ID = "movie_id";
if(intent != null && intent.hasExtra(MOVIE_ID)){
movieId = intent.getIntExtra(MOVIE_ID, 49026);
}
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.reviews_recyclerview);
linearLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(linearLayoutManager);
movieReviews.add(0, new Reviews("test", "TESTING"));
movieReviews.add(1, new Reviews("test", "TESTING"));
movieReviews.add(2, new Reviews("tset", "TESTING"));
mAdapter = new MyAdapter(movieReviews);
mRecyclerView.setAdapter(mAdapter);
return rootView;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
}
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
private List<Reviews> mDataset;
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView mTextView;
public ViewHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView;
}
}
public MyAdapter(List<Reviews> reviews){
mDataset = reviews;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.review_list_item, parent, false);
ViewHolder vh = new ViewHolder(view);
return vh;
}
#Override
public void onBindViewHolder(MyAdapter.ViewHolder holder, int position) {
holder.mTextView.setText(mDataset.get(position).getAuthor());
}
#Override
public int getItemCount() {
return mDataset.size();
}
}
I'm not sure what the problem could be.
Here is the review_fragment xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="#+id/reviews_recyclerview"/>
</LinearLayout>
Here is the activity_review xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/review_activity"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
The LayoutManager isn't null, your RecyclerView is.
You're inflating R.layout.activity_review instead of R.layout.review_fragment.
Because of this, mRecyclerView = (RecyclerView) rootView.findViewById(R.id.reviews_recyclerview); results in mRecyclerView being null.
Thus, make sure you inflate R.layout.review_fragment:
View rootView = inflater.inflate(R.layout.review_fragment, container, false);
In this line you're actually inflating the view of the activity:
View rootView = inflater.inflate(R.layout.activity_review, container, false);
But the recycler view you seek to find is not in that layout, but in the fragment layout. Change that line to:
View rootView = inflater.inflate(R.layout.review_fragment, container, false);

Categories

Resources