Issue
so i have a database that is filled with data about teachers, and when i try to open a fragment that has a recyclerView inside of it that displays all of the teachers in the database it crashes! and what makes this a bit more illogical is when i tries to make a toast that display the size of the list returned by the viewModel observer it returns the correct amount of teachers in database, same as when i tried to make a toast that display the name of the first entry in the list, it worked just fine
i apologize if the description of my problem isn't clear enough, am still a bit new nevertheless here is the code to my fragment that crashes when i open it :
public class AddHoursFragment extends Fragment {
private RecyclerView recyclerView;
private AddPaymentAdapter adapter;
private SchoolViewModel schoolViewModel;
private Button btn;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_add_hours, container, false);
btn = v.findViewById(R.id.btn_add_payment);
recyclerView = v.findViewById(R.id.rv_add_payment);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
schoolViewModel = new ViewModelProvider(this).get(SchoolViewModel.class);
schoolViewModel.getAllTeachers().observe(getViewLifecycleOwner(), new Observer<List<Teacher>>() {
@Override
public void onChanged(List<Teacher> teachers) {
adapter.setTeachers(teachers);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getContext(), teachers.get(0).getTeacherName()+"" , Toast.LENGTH_SHORT).show();
}
});
}
});
recyclerView.setAdapter(adapter);
return v;
}
here is the code of the adapter of the recyclerView inside the fragment :
public class AddPaymentAdapter extends RecyclerView.Adapter<AddPaymentAdapter.AddPaymentHolder> {
private List<Teacher> teachers = new ArrayList<>();
@NonNull
@Override
public AddPaymentHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.checkbox_row, parent, false);
return new AddPaymentHolder(v);
}
@Override
public void onBindViewHolder(@NonNull AddPaymentHolder holder, int position) {
Teacher teacher = teachers.get(position);
holder.checkBox.setText(teacher.getTeacherName());
}
@Override
public int getItemCount() {
return teachers.size();
}
public class AddPaymentHolder extends RecyclerView.ViewHolder {
CheckBox checkBox;
public AddPaymentHolder(@NonNull View itemView) {
super(itemView);
checkBox = itemView.findViewById(R.id.checkBox1);
}
}
public void setTeachers(List<Teacher> teachers){
this.teachers = teachers;
notifyDataSetChanged();
}
and this is what the logcat shows when the app crashes :
example.ecolemathphysique, PID: 7128
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.ecolemathphysique.Adapters.AddPaymentAdapter.setTeachers(java.util.List)' on a null object reference
at com.example.ecolemathphysique.AddHoursFragment$1.onChanged(AddHoursFragment.java:44)
at com.example.ecolemathphysique.AddHoursFragment$1.onChanged(AddHoursFragment.java:41)
Solution
You have a private field:
private AddPaymentAdapter adapter;
and you call in
adapter.setTeachers(teachers);
Cannot see in this code, but you like are missing the assignment to adapter
field.
Answered By - eeq
Answer Checked By - Dawn Plyler (JavaFixing Volunteer)