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);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.