Problem with RecyclerView and getFilter in Android Studio

All we need is an easy explanation of the problem, so here it is.

i am using recyclerview to display database. to use search I am using search view and Filterable interface. when in the search bar I start to enter the name, then the activity closes and throws it to the main screen.

Log

W/Filter: An exception occured during performFiltering()!
    java.lang.NullPointerException: Attempt to invoke interface method 'java.util.Iterator java.util.List.iterator()' on a null object reference
        at com.example.fixit.menu_java.service.CustomAdapter$1.performFiltering(CustomAdapter.java:82)
        at android.widget.Filter$RequestHandler.handleMessage(Filter.java:236)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:224)
        at android.os.HandlerThread.run(HandlerThread.java:67)
D/Surface: lockCanvas
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.grovers_repair, PID: 25967
    java.lang.NullPointerException: Attempt to invoke interface method 'void java.util.List.clear()' on a null object reference
        at com.example.fixit.menu_java.service.CustomAdapter$1.publishResults(CustomAdapter.java:97)
        at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:284)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:224)
        at android.app.ActivityThread.main(ActivityThread.java:7551)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)

Adapter

ArrayList<ServiceData> objDBData;
    private List<ServiceData> exampleList;
    private List<ServiceData> exampleListFull;


    public CustomAdapter(ArrayList<ServiceData> objDBData) {
        this.objDBData = objDBData;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View singleRow = LayoutInflater.from(parent.getContext()).inflate(R.layout.service_list,parent,false);
        return new MyViewHolder(singleRow);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        ServiceData objData = objDBData.get(position);
        holder.city_name.setText(objData.getCity_name());
        holder.company_name.setText(objData.getCompany_name());
        holder.map_name.setText(objData.getMap_name());
        holder.number.setText(objData.getNumber()+"");
    }

    @Override
    public int getItemCount() {
        return objDBData == null ? 0 : objDBData.size();
    }

    public static class MyViewHolder extends RecyclerView.ViewHolder{
        TextView city_name;
        TextView company_name;
        TextView map_name;
        TextView number;


        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            city_name = itemView.findViewById(R.id.city_card);
            company_name = itemView.findViewById(R.id.company_card);
            map_name = itemView.findViewById(R.id.map_card);
            number = itemView.findViewById(R.id.number_card);
        }
    }
    @Override
    public Filter getFilter() {
        return exampleFilter;
    }

    private Filter exampleFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            List<ServiceData> filteredList = new ArrayList<>();

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

                for (ServiceData item : exampleListFull) {
                    if (item.getCity_name().toLowerCase().contains(filterPattern)) {
                        filteredList.add(item);
                    }
                }
            }

            FilterResults results = new FilterResults();
            results.values = filteredList;

            return results;
        }

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

}

NewListService

public class NewListService extends AppCompatActivity {
    MyDatabaseHelper myDB;
    ArrayList<ServiceData> list;
    CustomAdapter customAdapter;
    RecyclerView recyclerView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_list_service);
        recyclerView = findViewById(R.id.service_recycler);
        myDB = new MyDatabaseHelper(this);
        list = new ArrayList<>();
        showData(recyclerView);

    }
    public void showData(View view){
        try {
            list = myDB.getAllData();
            customAdapter = new CustomAdapter(list);
            recyclerView.hasFixedSize();
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            recyclerView.setAdapter(customAdapter);
        } catch (Exception e) {
            Toast.makeText(this, "show data"+e.getMessage(), Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }
    }



    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.example_menu, menu);

        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) searchItem.getActionView();

        searchView.setImeOptions(EditorInfo.IME_ACTION_SEARCH);

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

            }

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


MyDatabaseHelper

public class MyDatabaseHelper extends SQLiteAssetHelper {
    private static final String DATABASE_NAME = "services.db";
    private static final int DATABASE_VERSION = 1;
    Context context;


    public MyDatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.context = context;
        setForcedUpgrade(1);
    }
    public ArrayList<ServiceData> getAllData(){
        try {
            ArrayList<ServiceData> list = new ArrayList<>();
            SQLiteDatabase sqLiteDatabase = getWritableDatabase();
            if(sqLiteDatabase != null){
                Cursor cursor = sqLiteDatabase.rawQuery("select * from locate",null);
                if(cursor.getCount() != 0){
                            while (cursor.moveToNext()){
                                String city_name = cursor.getString(1);
                                String company_name = cursor.getString(2);
                                String map_name = cursor.getString(3);
                                String number = cursor.getString(4);
                                String web = cursor.getString(5);
                                String geo = cursor.getString(6);
                                list.add(new ServiceData(city_name,company_name,
                                        map_name,number,web,geo));
                            }
                            return list;
                }
                else {
                    Toast.makeText(context, "No data retired", Toast.LENGTH_SHORT).show();
                    return null;
                }
            }
            else {
                Toast.makeText(context, "Data is null", Toast.LENGTH_SHORT).show();
                return null;
            }


        } catch (Exception e) {
            Toast.makeText(context, "getalldata" + e.getMessage(), Toast.LENGTH_SHORT).show();
            e.printStackTrace();
            return null;
        }
    }
    public int getUpgradeVersion() {

        SQLiteDatabase db = getReadableDatabase();
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

        String [] sqlSelect = {"MAX (version)"};
        String sqlTables = "upgrades";

        qb.setTables(sqlTables);
        Cursor c = qb.query(db, sqlSelect, null, null,
                null, null, null);

        int v = 0;
        c.moveToFirst();
        if (!c.isAfterLast()) {
            v = c.getInt(0);
        }
        c.close();
        return v;
    }
}

please help me figure out what the problem is

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

You have not instantiated the Lists exampleList and exampleListFull. Default values are null.

Calling clear() on a null object instead of a List throws the infamous NullPointerException.

And for the iterator error, you are calling addAll(exampleListFull) which means that it tries to iterate over a null object.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply