Android Autocompletetextview with Custom Adapter Filtering Not Working

Android AutoCompleteTextView with Custom Adapter filtering not working

I have to over-ride the getFilter() method of the Adapter

Here is the code which worked for me, thanks to sacoskun

public class CustomerAdapter extends ArrayAdapter<Customer> {
private final String MY_DEBUG_TAG = "CustomerAdapter";
private ArrayList<Customer> items;
private ArrayList<Customer> itemsAll;
private ArrayList<Customer> suggestions;
private int viewResourceId;

public CustomerAdapter(Context context, int viewResourceId, ArrayList<Customer> items) {
super(context, viewResourceId, items);
this.items = items;
this.itemsAll = (ArrayList<Customer>) items.clone();
this.suggestions = new ArrayList<Customer>();
this.viewResourceId = viewResourceId;
}

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);
}
Customer customer = items.get(position);
if (customer != null) {
TextView customerNameLabel = (TextView) v.findViewById(R.id.customerNameLabel);
if (customerNameLabel != null) {
// Log.i(MY_DEBUG_TAG, "getView Customer Name:"+customer.getName());
customerNameLabel.setText(customer.getName());
}
}
return v;
}

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

Filter nameFilter = new Filter() {
@Override
public String convertResultToString(Object resultValue) {
String str = ((Customer)(resultValue)).getName();
return str;
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
if(constraint != null) {
suggestions.clear();
for (Customer customer : itemsAll) {
if(customer.getName().toLowerCase().startsWith(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) {
ArrayList<Customer> filteredList = (ArrayList<Customer>) results.values;
if(results != null && results.count > 0) {
clear();
for (Customer c : filteredList) {
add(c);
}
notifyDataSetChanged();
}
}
};

}

Custom ArrayAdapter AutoCompleteTextView not triggering

For auto suggestions to work, in autocomplete textview, we have to over-ride getFilter(), where we set the filter functionality, the default adapter can only filter strings, and you are using an object Customer

So you need to do the following in you :

@NonNull
@Override
public Filter getFilter() {

return new Filter() {
final Object object = new Object();

@Override
public String convertResultToString(Object resultValue) {
return resultValue.toString();

}

@Override
protected FilterResults performFiltering(CharSequence constraint) {

FilterResults filterResults = new FilterResults();
List<Customer> customers = new ArrayList<>();

if (constraint != null) {

for (Customer customer : customerList) {
if (department instanceof SearchableStrings) {
if (customer.getname().toLowerCase().contains(constraint.toString().toLowerCase())) {
customers.add(customer);

}

}
if (customers.size() > 1) {
filterResults.values = customers;
filterResults.count = customers.size();
} else {
filterResults.values = null;
filterResults.count = 0;

}

}
//notifyDataSetChanged();
return filterResults;
}

@Override
protected void publishResults(CharSequence constraint, FilterResults results) {

// mObjects.clear();
if (results != null && results.count > 0) {
clear();
// avoids unchecked cast warning when using customerList.addAll((ArrayList<Customer>) results.values);
for (Object object : (List<?>) results.values) {
add(object);

}
notifyDataSetChanged();
}
}

};

Android AutoCompleteTextView with custom Adapter

in this line
CustomerSuggestion customerSuggestion = filteredList.get(position);
try to use the original list not the filtered one, like below.

CustomerSuggestion customerSuggestion = customerSuggestions.get(position);

After some search I believe that this happens because the main list of this kind of adapter is the original one not the filtered one, so get view method is called referring to the original list!

How to make custom Filter for AutoCompleteTextView using custom Adapter?

It says in the documentation of ArrayAdapter that:

@throws UnsupportedOperationException if the underlying data collection is immutable

Therefore you should be passing in a MutableList into the ArrayAdapter if you want to use clear(), either by constructing FornitoriAdapter with one, or converting it with Collection<T>.toMutableList().

Android AutoComplete TextView with Custom ArrayAdapter and with Firestore not working

You are dealing with network request and it is not sequential. What it means - by the time adapter is created and set to the auto object the network request that returns a list of songs is not yet finished. Or maybe it has finished successfully, or maybe failed - no one knows.

Thus, from the OnCompleteListener you must make sure you update the list of songs and adapter. When the list is updated from onComplete method - your adapter knows nothing about that update. It does not watch changes in the array by itself.

You have to do a few things:

  1. When network request is finished - make sure activity is not finished. Otherwise, you can end up with a crashing application (that will be hard to debug);
  2. Make sure you notify the adapter about changes in the list of songs.
db.collection("Songs_names").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
// Step 1: if activity is no longer valid to use just skip this "task" response.
if (isFinishing() || isDestroyed()) return;

if(task.isSuccessful()){
if (task.getResult() != null) {
for (QueryDocumentSnapshot document : task.getResult()) {
Log.d("tag","msg " + document.getString("name"));
songs.add(new Songs(document.getString("name")));
Log.d("show objects","showed" + songs);

// Step 2: songs are updated
adapter.updateList(songs);
}

}
}
}
});

Now you have to modify your adapter a little bit. A new method is added that accepts a list of songs and notifies adapter about the changes.

public class songs_auto_adapter extends ArrayAdapter<Songs> {
private List<Songs> songsFull;
private Touch touch;
public songs_auto_adapter(@NonNull Context context, @NonNull List<Songs> objects,Touch touch) {
super(context,0, objects);
songsFull = new ArrayList<>(objects);
this.touch = touch;
}

public void updateList(@NonNull List<Songs> newList) {
songsFull = new ArrayList<>(newList);
clear();
addAll(songsFull); // Adapter is now aware of the updated list
}

...

}

AutoCompleteTextView items are not clickable when using custom item layout

I am having the same issue as you. You will have to make your own onItemClick event. Following this tutorial, you would need to set your own onItemClickListener.

It should look like this:

    autoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// click event (such as filling the autocomplete section)
}
});

edit: I did not see your comment. Another thing I had to do was to set android:descendantFocusability="blocksDescendants" in the <LinearLayout> from the xml file. Source



Related Topics



Leave a reply



Submit