1

I am working on a search feature for my app. I implemented Filterable method to my Home Adapter. My array list is throwing a null pointer exception and I have seen many other similar questions in which the problem was not initializing the array list. However, I have in the following code, but I'm not sure if its initialized in the right place. Please advise me on how to correct this. Thanks.

This is the error I'm getting:

enter image description here

My Home Adapter Code is as follows:

package com.example.oddsynew.Home;

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.oddsynew.Modals.Job;
import com.example.oddsynew.R;
import com.squareup.picasso.Picasso;

import java.util.ArrayList;
import java.util.List;

public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder> implements Filterable {

    Context context;
    ArrayList<Job> jobs, jobsListFull;



    public HomeAdapter(Context c, ArrayList<Job> j) {
        context = c;
        jobs = j;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.job_row, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
        holder.recruiterName.setText(jobs.get(position).getRecruiter_name());
        holder.jobName.setText(jobs.get(position).getJob_name());
        holder.jobLocation.setText(jobs.get(position).getLocation());
        holder.jobCharge.setText(jobs.get(position).getJob_charge());
        Picasso.get().load(jobs.get(position).getProf_pic()).into(holder.profPic);

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    Intent intent = new Intent(context, JobInfo.class);
                    intent.putExtra("recruiterName", jobs.get(holder.getAdapterPosition()).getRecruiter_name());
                    intent.putExtra("jobName", jobs.get(holder.getAdapterPosition()).getJob_name());
                    intent.putExtra("jobCharge", jobs.get(holder.getAdapterPosition()).getJob_charge());
                    intent.putExtra("jobLocation", jobs.get(holder.getAdapterPosition()).getLocation());
                    intent.putExtra("profPic", jobs.get(holder.getAdapterPosition()).getProf_pic());
                    intent.putExtra("startDate", jobs.get(holder.getAdapterPosition()).getStart_date());
                    intent.putExtra("endDate", jobs.get(holder.getAdapterPosition()).getEnd_date());
                    intent.putExtra("startTime", jobs.get(holder.getAdapterPosition()).getStart_time());
                    intent.putExtra("endTime", jobs.get(holder.getAdapterPosition()).getEnd_time());
                    intent.putExtra("jobDesc", jobs.get(holder.getAdapterPosition()).getJob_desc());
                    intent.putExtra("jobTasks", jobs.get(holder.getAdapterPosition()).getJob_tasks());
                    intent.putExtra("addPref", jobs.get(holder.getAdapterPosition()).getAdd_pref());
                    intent.putExtra("jobID", jobs.get(holder.getAdapterPosition()).getJobID());
                    context.startActivity(intent);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return jobs.size();
    }

    @Override
    public Filter getFilter() {
        return searchFilter;
    }

    private Filter searchFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            ArrayList<Job> filteredList = new ArrayList<>();

            if(constraint == null || constraint.length() == 0){
                filteredList.addAll(jobsListFull);
            }else{
                String filterPattern = constraint.toString().toLowerCase().trim();

                for(Job job: jobsListFull){
                    if(job.getJob_name().toLowerCase().contains(filterPattern)){
                        filteredList.add(job);
                    }
                }
            }
            FilterResults results = new FilterResults();
            results.values = filteredList;

            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            jobs.clear();
            jobs.addAll((List) results.values);
            notifyDataSetChanged();

        }
    };

    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView recruiterName, jobName, jobLocation, jobCharge;
        ImageView profPic;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            recruiterName = itemView.findViewById(R.id.recruiterName);
            jobName = itemView.findViewById(R.id.jobName);
            jobLocation = itemView.findViewById(R.id.jobLocation);
            jobCharge = itemView.findViewById(R.id.jobCharge);
            profPic = itemView.findViewById(R.id.prof_pic);
        }
    }

    public HomeAdapter(ArrayList<Job> jobs) {
        this.jobs = jobs;
        jobsListFull = new ArrayList<>(jobs);
    }
}

And this is my search class:

package com.example.oddsynew;

import android.os.Bundle;
import android.widget.SearchView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.oddsynew.Home.HomeAdapter;
import com.example.oddsynew.Modals.Job;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;

public class Search extends AppCompatActivity {

    DatabaseReference myRef;
    RecyclerView newJobList;
    ArrayList<Job> list;
    HomeAdapter adapter;
    SearchView searchView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);

        newJobList = (RecyclerView) findViewById(R.id.jobRecyclerView);

        searchView = (SearchView) findViewById(R.id.search);

        try {
            newJobList.setLayoutManager(new LinearLayoutManager(Search.this));
            list = new ArrayList<Job>();

            adapter = new HomeAdapter(Search.this, list);
            newJobList.setAdapter(adapter);

            myRef = FirebaseDatabase.getInstance().getReference().child("Jobs");
            myRef.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    for (DataSnapshot ds : dataSnapshot.getChildren()) {
                        Job j = ds.getValue(Job.class);
                        list.add(j);
                    }
                    System.out.println(list);
                    adapter.notifyDataSetChanged();
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                    Toast.makeText(Search.this, "Error", Toast.LENGTH_SHORT).show();
                }
            });

            searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                @Override
                public boolean onQueryTextSubmit(String query) {
                    return false;
                }

                @Override
                public boolean onQueryTextChange(String newText) {
                    adapter.getFilter().filter(newText);
                    return false;
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

SOLUTION: With IntelliJ Amiya's help I came up with the following corrected code.

 @Override
    public Filter getFilter() {
        return searchFilter;
    }

    private Filter searchFilter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                String charString = charSequence.toString();
                if (charString.isEmpty()) {
                    jobs = jobsListFull;
                } else {
                    ArrayList<Job> filteredList = new ArrayList<>();
                    for (Job row : jobsListFull) {


                        if (row.getJob_name().toLowerCase().contains(charString.toLowerCase())) {
                            filteredList.add(row);
                        }
                    }

                    jobs = filteredList;
                }

                FilterResults filterResults = new FilterResults();
                filterResults.values = jobs;
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                jobs = ((ArrayList) filterResults.values);
                notifyDataSetChanged();
            }
        };

    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView recruiterName, jobName, jobLocation, jobCharge;
        ImageView profPic;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            recruiterName = itemView.findViewById(R.id.recruiterName);
            jobName = itemView.findViewById(R.id.jobName);
            jobLocation = itemView.findViewById(R.id.jobLocation);
            jobCharge = itemView.findViewById(R.id.jobCharge);
            profPic = itemView.findViewById(R.id.prof_pic);
        }
    }
1
  • Yes I know. But I don't understand why. Commented Apr 30, 2020 at 14:46

1 Answer 1

1

jobs.addAll((List) results.values);

addAll() appends all of the elements in the specified collection to the end of this list, in the order that they are returned by the specified collection's Iterator.

 @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            jobs.clear();
            jobs.addAll((List) results.values); // Issue here
            notifyDataSetChanged();

        }
    };

In Java, a special null value can be assigned to an object reference. NullPointerException is thrown when an application attempts to use an object reference that has the null value.

Your (List) results.values return null. At first debug (Add Break-point) that values are present or not FilterResults results. Before cast to List make sure results.values having data.

CODE EDIT

package com.example.oddsynew.Home;

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.oddsynew.Modals.Job;
import com.example.oddsynew.R;
import com.squareup.picasso.Picasso;

import java.util.ArrayList;
import java.util.List;

public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder> implements Filterable {

    Context context;

    private ArrayList<Job> alListData;
    private ArrayList<Job> alListFiltered;


    public HomeAdapter(Context c, ArrayList<Job> j) {
         context = c;
         this.alListData = j;
         this.alListFiltered = j;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.job_row, parent, false));
    }

    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
        holder.recruiterName.setText(alListFiltered.get(position).getRecruiter_name());
        holder.jobName.setText(alListFiltered.get(position).getJob_name());
        holder.jobLocation.setText(alListFiltered.get(position).getLocation());
        holder.jobCharge.setText(alListFiltered.get(position).getJob_charge());
        Picasso.get().load(alListFiltered.get(position).getProf_pic()).into(holder.profPic);

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    Intent intent = new Intent(context, JobInfo.class);
                    intent.putExtra("recruiterName", alListFiltered.get(holder.getAdapterPosition()).getRecruiter_name());
                    intent.putExtra("jobName", alListFiltered.get(holder.getAdapterPosition()).getJob_name());
                    intent.putExtra("jobCharge", alListFiltered.get(holder.getAdapterPosition()).getJob_charge());
                    intent.putExtra("jobLocation", alListFiltered.get(holder.getAdapterPosition()).getLocation());
                    intent.putExtra("profPic", alListFiltered.get(holder.getAdapterPosition()).getProf_pic());
                    intent.putExtra("startDate", alListFiltered.get(holder.getAdapterPosition()).getStart_date());
                    intent.putExtra("endDate", alListFiltered.get(holder.getAdapterPosition()).getEnd_date());
                    intent.putExtra("startTime", alListFiltered.get(holder.getAdapterPosition()).getStart_time());
                    intent.putExtra("endTime", alListFiltered.get(holder.getAdapterPosition()).getEnd_time());
                    intent.putExtra("jobDesc", alListFiltered.get(holder.getAdapterPosition()).getJob_desc());
                    intent.putExtra("jobTasks", alListFiltered.get(holder.getAdapterPosition()).getJob_tasks());
                    intent.putExtra("addPref", alListFiltered.get(holder.getAdapterPosition()).getAdd_pref());
                    intent.putExtra("jobID", alListFiltered.get(holder.getAdapterPosition()).getJobID());
                    context.startActivity(intent);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return alListFiltered.size();
    }

    @Override
    public Filter getFilter() {
        return searchFilter;
    }

    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                String charString = charSequence.toString();
                if (charString.isEmpty()) {
                    alListFiltered = alListData;
                } else {
                    List<Job> filteredList = new ArrayList<>();
                    for (Job row : alListData) {


                        if (row.getJob_name().toLowerCase().contains(charString.toLowerCase())) {
                            filteredList.add(row);
                        }
                    }

                    alListFiltered = filteredList;
                }

                FilterResults filterResults = new FilterResults();
                filterResults.values = alListFiltered;
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                alListFiltered = (ArrayList<Job>) filterResults.values;
                notifyDataSetChanged();
            }
        };
    }


    class MyViewHolder extends RecyclerView.ViewHolder {
        TextView recruiterName, jobName, jobLocation, jobCharge;
        ImageView profPic;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            recruiterName = itemView.findViewById(R.id.recruiterName);
            jobName = itemView.findViewById(R.id.jobName);
            jobLocation = itemView.findViewById(R.id.jobLocation);
            jobCharge = itemView.findViewById(R.id.jobCharge);
            profPic = itemView.findViewById(R.id.prof_pic);
        }
    }

}
Sign up to request clarification or add additional context in comments.

8 Comments

I'm new to android. Can you advise me on how to fix this? Do you mean to say my results is returning null?
Thanks! I debugged. So apparently, my results is null. I'm trying to figure out why. If you catch something, please let me know.
@Devika.S @Override protected void publishResults(CharSequence charSequence, FilterResults filterResults) { jobs = (ArrayList<Job>) filterResults.values; notifyDataSetChanged(); }
@Devika.S remove public HomeAdapter(ArrayList<Job> jobs) { this.jobs = jobs; jobsListFull = new ArrayList<>(jobs); }
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.