Search code examples
androidarraylistmultiple-columnssearchviewcustom-adapter

I have a 3 column Listview with data from SQLite DB and a seachview window. i created a custom data. The search is not properly executed


I have created a MultiColumn ListView with a SearchView above it. It pulls data from an SQLite database and displays in the list view. I have created a custom ArrayAdapter and the java class. However, the output from my SearchView on my 3 column custom array list view is not returning the correct data i.e. it is not filtering correctly. I have tried everything to figure what may be the issue, and been on this for the last 3 days. I am using the QueryTextChangeListerner. Any help with be appreciated, as I am at a bottleneck in my app development.

MainActivity.java:

        mSearchView = (SearchView) findViewById(R.id.search_view);
        listView = (ListView) findViewById(R.id.list_view);

        controller = new ResturantsDbHelper(this);

        userList = new ArrayList<>();

        Cursor resturantdata = controller.getResturantList();

        int numRows =resturantdata.getCount();
        if (numRows == 0) {
            Toast.makeText(SearchResturantListingX.this,"No Resturants matching your selection criteria",Toast.LENGTH_LONG).show();
        }
        else {
            while (resturantdata.moveToNext()) {
                user = new User(resturantdata.getString(1),resturantdata.getString(2),resturantdata.getString(3),resturantdata.getString(4),resturantdata.getString(5));

                userList.add(user);
            }
            //FINISH Populating the array variable with the string data from SQLIte database

            adapter = new FiveColumn_ListAdapter(this,R.layout.activity_search_main3_resturant_list,userList);

            listView.setAdapter(adapter);
        }

        listView.setTextFilterEnabled(true);
        setupSearchView();
    }

    private void setupSearchView() {
        mSearchView.setIconifiedByDefault(false);
        mSearchView.setOnQueryTextListener(this);
        mSearchView.setSubmitButtonEnabled(true);
        mSearchView.setQueryHint("Search Here By Name");
    }

    @Override
    public boolean onQueryTextSubmit(String query) {
        return false;
    }

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

Here is my Java class which defines my ListItems:

public class User {
    private String resturantName;
    private String resturantType;
    private String resturantLocation;

    public User (String resturantName, String resturantType, String resturantLocation, String rOpening, String rClosing){
        super();
        this.resturantName = resturantName;
        this.resturantType = resturantType;
        this.resturantLocation = resturantLocation;
    }

    public String getResturantName() {
        return resturantName;
    }

    public void setResturantName (String resturantName) {
        this.resturantName = resturantName;
    }

    public String getResturantType() {
        return resturantType;
    }

    public void setType (String resturantType) {
        this.resturantType = resturantType;
    }

    public String getResturantLocation() {
        return resturantLocation;
    }

    public void setLocation (String resturantLocation) {
        this.resturantLocation = resturantLocation;
    }

    public User(String resturantName, String type, String location) {
        super();
        this.resturantName = resturantName;
    }

    @Override
    public String toString() {
        return  resturantName + " ";  
    }
}

Here is my custom Adapter:

public class FiveColumn_ListAdapter extends ArrayAdapter<User> {

    private LayoutInflater mInflater;
    private ArrayList<User> users;
    private int mViewResourceId;

    public FiveColumn_ListAdapter(Context context, int textViewResourceId, ArrayList<User> users) {
        super(context,textViewResourceId,users);
        this.users = users;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mViewResourceId = textViewResourceId;
    }

    public View getView(int position, View convertView, ViewGroup parents) {
        convertView = mInflater.inflate(mViewResourceId,null);

        User user =users.get(position);

        if (user != null) {
            TextView name=(TextView)convertView.findViewById(R.id.resturantName);
            TextView type=(TextView)convertView.findViewById(R.id.resturantType);
            TextView location=(TextView)convertView.findViewById(R.id.resturantLocation);

            if(name !=null) {
                name.setText((user.getResturantName()));
            }

            if(type !=null) {
                type.setText((user.getResturantType()));
            }

            if(location !=null) {
                location.setText((user.getResturantLocation()));
            }

        }
        return convertView;
    }
}

Solution

  • FiveColumn_ListAdapter must implement android.widget.Filterable

    then add these codes to FiveColumn_ListAdapter:

    public class FiveColumn_ListAdapter extends ArrayAdapter<User> 
                                    implements android.widget.Filterable {
    
    private LayoutInflater mInflater;
    private ArrayList<User> users;// this is filtered users a subset of AllUsers
    private int mViewResourceId;
    private ArrayList<User> AllUsers;// AllUsers is users without any filter
    
    public FiveColumn_ListAdapter(Context context, int textViewResourceId, 
                                                 ArrayList<User> users, String initialQuery) {
        super(context,textViewResourceId,users);
        this.AllUsers = users;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mViewResourceId = textViewResourceId;
        getFilter().filter(initialQuery);// perform fiter to populate users filter may be empty String
    }
    
        @Override
        public Filter getFilter() {
            return new Filter() {
                @Override
                protected FilterResults performFiltering(CharSequence query) {
    
                    FilterResults filterResults = new FilterResults();
                    if(AllUsers == null || AllUsers.size() == 0){
                         filterResults.count = 0;
                         filterResults.values = null;
                         return filterResults;
                    }
                    ArrayList<User> results = new ArrayList<>();
                    for (User user : AllUsers) {
                          if(query.toString().equals(user.getResturantName())// do any filtering here
                             results.add(user);
                    }
                    filterResults.count = results.size();
                    filterResults.values = results;
                    return filterResults;
                }
                ///////////////////////////////
                @Override
                protected void publishResults(CharSequence constraint, FilterResults results) {
                    users = results.values// 
                }
            };
        }