I am trying to display a list of journal entries in my recycler view but I am getting the following error:
Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setLayoutManager(androidx.recyclerview.widget.RecyclerView$LayoutManager)' on a null object reference
This is the piece of code which seems to invoke the error:
recyclerView = findViewById(R.id.myRecyclerViewOneandOnly);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
I've seen this post: setLayoutManager NullPointException in RecyclerView, but I checked my setContentView: setContentView(R.layout.activity_journal_list);
and it seems fine as it corresponds to the right layout file with the recycler view:
Later on in the code, I set the adapter as well:
recyclerViewAdapter = new RecyclerViewAdapter(JournalList.this, journalsList);
recyclerView.setAdapter(recyclerViewAdapter);
recyclerViewAdapter.notifyDataSetChanged();
Full JournalList.java
code:
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import com.google.firebase.storage.StorageReference;
import com.krish.journalapp.data.JournalApi;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class JournalList extends AppCompatActivity {
private FirebaseAuth firebaseAuth;
private FirebaseAuth.AuthStateListener myListener;
private FirebaseUser mUser;
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private StorageReference storageReference;
private List<Journal> journalsList;
private RecyclerView recyclerView;
private RecyclerViewAdapter recyclerViewAdapter;
private CollectionReference mCollection = db.collection("Journal");
private TextView noJournalEntrysFound;
@Override
protected void onCreate(Bundle savedInstanceState) {
firebaseAuth = FirebaseAuth.getInstance();
mUser = firebaseAuth.getCurrentUser();
journalsList = new ArrayList<>();
noJournalEntrysFound = findViewById(R.id.textAddSomethingIfNot);
recyclerView = findViewById(R.id.myRecyclerViewOneandOnly);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_journal_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(toolbar);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.addItem:
//add another journal entry
if(mUser != null && firebaseAuth != null){
startActivity(new Intent(JournalList.this, PostJournal.class));
}
break;
case R.id.log_out:
if(mUser != null && firebaseAuth != null){
firebaseAuth.signOut();
startActivity(new Intent(JournalList.this, MainActivity.class));
//finish();
}
//log out of account
break;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onStart() {
mCollection.whereEqualTo("userId", JournalApi.getInstance().getId()).get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
if(!queryDocumentSnapshots.isEmpty()){
for(QueryDocumentSnapshot journals : queryDocumentSnapshots){
Journal myJournale = journals.toObject(Journal.class);
journalsList.add(myJournale);
}
//we are passing in JournalList.this, but that will go into the context for the recycler view to inflate FROM, isn't this a problem??
recyclerViewAdapter = new RecyclerViewAdapter(JournalList.this, journalsList);
recyclerView.setAdapter(recyclerViewAdapter);
recyclerViewAdapter.notifyDataSetChanged();
}else{
noJournalEntrysFound.setVisibility(View.VISIBLE);
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull @NotNull Exception e) {
Log.d("TAG", e.toString());
}
});
super.onStart();
}
}
Full RecyclerViewAdapter code:
import android.content.Context;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.JournalListHolder> {
private Context context;
private List<Journal> journalList;
public RecyclerViewAdapter(Context context, List<Journal> journalList) {
this.context = context;
this.journalList = journalList;
}
@NonNull
@NotNull
@Override
public JournalListHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.journal_list_view, parent, false);
return new JournalListHolder(view, context);
}
@Override
public void onBindViewHolder(@NonNull @NotNull RecyclerViewAdapter.JournalListHolder holder, int position) {
Journal myJournal = journalList.get(position);
String imageUrl;
holder.titleSent.setText(myJournal.getTitle());
holder.thoughtSent.setText(myJournal.getThought());
imageUrl = myJournal.getImagePath();
String timeAgo = (String) DateUtils.getRelativeTimeSpanString(myJournal.getTimeAdded().getSeconds() * 1000);
holder.dateSent.setText(timeAgo);
//use picasso library to downlaod and show image
Picasso.get().load(imageUrl).placeholder(R.drawable.cheese).fit().into(holder.imageSent);
}
@Override
public int getItemCount() {
return journalList.size();
}
class JournalListHolder extends RecyclerView.ViewHolder{
ImageView imageSent;
TextView titleSent, thoughtSent, dateSent;
public JournalListHolder(@NonNull @NotNull View itemView, Context ctx) {
super(itemView);
ctx = context;
imageSent = itemView.findViewById(R.id.imageSent);
titleSent = itemView.findViewById(R.id.titleSent);
thoughtSent = itemView.findViewById(R.id.thoughtSent);
dateSent = itemView.findViewById(R.id.dateSent);
}
}
}
Thank you!