0

I am trying to use AutoCompleteTextView for filtering and I'm having a problem with the filter. It returns all the Items in the ArrayList instead of the filtered ones. Below is my code:

 Filter nameFilter = new Filter() {
    @Override
    public String convertResultToString(Object resultValue) {
        String str = ((State)(resultValue)).getName();
        Log.e("Conv"+TAG, str);
        return str;
    }
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        if(constraint != null) {
            suggestions.clear();
            for (State customer : itemsAll) {
                Log.e("Ite "+TAG, "" + itemsAll.size());
                Log.e("Cons " + TAG, constraint.toString());
                Log.e("Sta" + TAG, customer.getName()); //This is always null
                if(customer.getName().toLowerCase().contains(constraint.toString().toLowerCase())) {
                    suggestions.add(customer);
                }
            }
            FilterResults filterResults = new FilterResults();
            filterResults.values = suggestions;
            filterResults.count = suggestions.size();
            return filterResults;
        } else {
            return new FilterResults();
        }
    }
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        List<State> filteredList = (ArrayList<State>) results.values;
        if(results != null && results.count > 0) {
            clear();
            Log.e("D "+TAG, ""+results.count);
            for (State c : filteredList) {
                Log.e("The "+TAG, c.getName() + " " + c.getId());
                add(c);
                notifyDataSetChanged();
            }
        } else {
            Log.e(TAG, "Empty Filter");
            notifyDataSetChanged();
        }
    }
};

And then I started logging around and I noticed this line is always null Log.e("Sta" + TAG, customer.getName()); //This is always null while this line Log.e("Cons " + TAG, constraint.toString()); and this line Log.e("Ite "+TAG, "" + itemsAll.size()); is never null. Constraint can't be null for sure unless no text was passed. But, for first object to be null when itemsAll.size() is not null or empty. I am confused. And below, is my List initialization

private static final String TAG = "StateAdapter";
private ArrayList<State> items;
private ArrayList<State> itemsAll;
private ArrayList<State> suggestions;
private Context context;
private int viewResourceId;

public StateAutoCompleteAdapter(Context context, int resource, int textViewResourceId, ArrayList<State> objects) {
    super(context, resource, textViewResourceId, objects);
    this.context = context;
    this.items = objects;
    this.itemsAll = new ArrayList<State>(items);
    this.suggestions = new ArrayList<State>();
    this.viewResourceId = resource;
}

And for the getView function

public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(viewResourceId, null);
    }
    State customer = items.get(position);
    if (customer != null) {
        TextView customerNameLabel = (TextView) v.findViewById(R.id.bakerName);
        TextView bakerAddress = (TextView) v.findViewById(R.id.bakerAddress);
        if (customerNameLabel != null) {
//              Log.i(MY_DEBUG_TAG, "getView Customer Name:"+customer.getName());
            customerNameLabel.setText(customer.getName());
            bakerAddress.setVisibility(View.GONE);
        }
    }
    return v;
}
Tonespy
  • 3,257
  • 7
  • 26
  • 52
  • If customer.getName() is null then you would have a NullPointerException one line below it. You didn't mention what you get in publishResults(), I'm assuming you get "empty filter"? Also, I'm assuming you're extending ArrayAdapter, which you shouldn't do if you plan to use custom filtering as that adapter is designed for standard scenarios. – user Apr 29 '16 at 17:01
  • where is your data taken from? – pskink Apr 29 '16 at 17:02
  • @pskink I'm fetching the data from the `Realmdb` and it's fetching fine. That's why I can get the count – Tonespy Apr 29 '16 at 17:08
  • @Luksprog This line is always null too `Log.e("The "+TAG, c.getName() + " " + c.getId());` – Tonespy Apr 29 '16 at 17:09
  • so why are you filtering your data "by hand" if you have sql db engine? it kills the whole idea of having fast database – pskink Apr 29 '16 at 17:12
  • Well, @pskink I tried to filter using the fast db, but the data wasn't being displayed. Because, I was filtering based on the text being inputed into the `AutoCompleteTextView` and I don't seem to know how I can wire it directly to the `Listview` being shown on the `AutoCompleteTextView` so, I'm stuck with fetching and filter – Tonespy Apr 29 '16 at 17:22
  • does `realmdb` have something similar to `CursorAdapter`? [this](http://stackoverflow.com/a/19860624/2252830) link shows how it can be easy wired by using standard `SimpleCursorAdapter` – pskink Apr 29 '16 at 17:23
  • @pskink `Realm` doesn't have a `CursorAdapter`. Just a normal `BaseAdapter` here is it https://realm.io/docs/java/latest/#working-with-android – Tonespy Apr 29 '16 at 17:30
  • didnt you think of using std built-in sqlite db or some ORM based on it like GreenDAO? – pskink Apr 29 '16 at 17:37
  • Well, I could've switched to used an sqlite built on it, but it's an inherited project. And everything is wired to Realm. So, that explains it @pskink – Tonespy Apr 29 '16 at 17:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/110676/discussion-between-ituoke-ajanlekoko-and-pskink). – Tonespy Apr 29 '16 at 20:07

2 Answers2

1

So, I fixed the problem myself doing this. So, I use a normal BaseAdapter and extend Filterable So, for those that may need how to use RealmDB with AutoCompleteTextView there you go

 public class LgasAutoCompleteAdapter extends BaseAdapter implements Filterable {

private static final String TAG = "LgasAutoComp";
private Context mContext;
private List<Lga> mResult = new ArrayList<>();
private LayoutInflater inflater;

public LgasAutoCompleteAdapter(Context mContext) {
    this.mContext = mContext;
}

@Override
public int getCount() {
    return mResult.size();
}

@Override
public Object getItem(int position) {
    return mResult.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View view, ViewGroup parent) {
    if (inflater == null)
        inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    if (view == null)
        view = inflater.inflate(R.layout.item_baker_autocomplete, parent, false);

    Lga lga = mResult.get(position);

    TextView customerNameLabel = (TextView) view.findViewById(R.id.bakerName);
    TextView bakerAddress = (TextView) view.findViewById(R.id.bakerAddress);

    if (lga != null) {
        if (customerNameLabel != null) {
//              Log.i(MY_DEBUG_TAG, "getView Customer Name:"+customer.getName());
            customerNameLabel.setText(lga.getName());
            bakerAddress.setVisibility(View.GONE);
        }
    }

    return view;
}

@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence charSequence) {
            return null;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults filterResults) {
            if (constraint != null) {
                //String query = constraint.toString().toLowerCase();
                mResult = filterStates(constraint.toString());
                Log.e(TAG, ""+mResult.size());
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    };
}

@NonNull
private List<Lga> filterStates(String query) {
    Realm mRealm = RealmUtils.getRealmInstance(mContext);
    return mRealm.where(Lga.class)
            .contains("name", query)
            .or()
            .beginsWith("name", query)
            .findAll();
}
}
Tonespy
  • 3,257
  • 7
  • 26
  • 52
0

clear() method might be causing problem. So please check its code for which array list you are cleaning.

Another problem is because you are using State customer = items.get(position); in getView() and using suggestions.add(customer); in performFiltering(CharSequence constraint)

Hope this helps.

Sandeep Sharma
  • 1,855
  • 3
  • 19
  • 34