问题
I have a autocomplete text view
in my android project which is working fine but it only works if first value is entered in it. So for making it more customizable, I have added the below class
public class CustomArrayAdapterWIthFilter extends ArrayAdapter<String> implements Filterable {
List<String> items = null;
List<String> originalItems = null;
private MyFilters myFilters = null;
Context mContext;
public CustomArrayAdapterWIthFilter(@NonNull Context context, @LayoutRes int resource, @NonNull List<String> objects) {
super(context, resource, objects);
this.items = new ArrayList<>();
items.addAll(objects);
this.originalItems = new ArrayList<>();
this.originalItems.addAll(objects);
mContext = context;
}
@Override
public int getCount() {
return items.size();
}
@Nullable
@Override
public String getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
@NonNull
@Override
public Filter getFilter() {
if (myFilters == null) {
myFilters = new MyFilters();
}
return myFilters;
}
class MyFilters extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults result = new FilterResults();
if (constraint != null && constraint.toString().length() > 0) {
ArrayList<String> filteredItems = new ArrayList<String>();
for (int i = 0, l = originalItems.size(); i < l; i++) {
String item = originalItems.get(i);
if (item.toString().toLowerCase().contains(constraint))
filteredItems.add(item);
}
result.count = filteredItems.size();
result.values = filteredItems;
} else {
synchronized (this) {
result.values = originalItems;
result.count = originalItems.size();
}
}
return result;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
items = (ArrayList<String>) results.values;
notifyDataSetChanged();
clear();
for (int i = 0, l = items.size(); i < l; i++)
add(items.get(i));
notifyDataSetInvalidated();
}
}
public void addItems(List<String> items) {
this.items = items;
notifyDataSetChanged();
}
In my fragment I have done the following
CustomArrayAdapterWIthFilter meterSrNumAdapter;
if (meterSrNumAdapter.getCount() == 0) {
meterSrArrayList = new MeterManager(getActivity()).getRefNoByStatus(Constants.SR_NO_UN_USED);
meterSrArrayList.add(installationDetails.getMsn());
meterSrNumAdapter.addItems(meterSrArrayList);
}
if (meterSrNumAdapter.getCount() == 0) {
meterSrArrayList = new MeterManager(getActivity()).getRefNoByStatus(Constants.SR_NO_UN_USED);
meterSrNumAdapter.addItems(meterSrArrayList);
}
meterSrArrayList = new ArrayList<String>();
meterSrNumAdapter = new CustomArrayAdapterWIthFilter(getActivity(), R.layout.custom_spinner_layout, meterSrArrayList);
smartMsnSpinner.setAdapter(meterSrNumAdapter);
smartMsnSpinner.setSingleLine(true);
smartMsnSpinner.setThreshold(1);
smartMsnSpinner.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
selectedMeterNo = adapterView.getItemAtPosition(i).toString();
Log.d("testtt", adapterView.getItemAtPosition(i).toString());
}
});
In above code smartMsnSpinner
is my autocomplete text view
When I run my app the autocomplete doesn't works. I have tried some other adapters which are placed over the internet. But still the result is same. I am trying for this custom adapter because in my another app it's working perfect and in this code I am doing the same.
Update 1
After the suggestion I have changed the custom adapter code while considering the other part of the code is same as added above
List<String> suggestionItems = null;
//In constructor
this.items = new ArrayList<>(objects);
this.originalItems = new ArrayList<>(objects);
mContext = context;
class MyFilters extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
if(constraint !=null)
{
suggestionItems.clear();
for(int i=0, i1 = originalItems.size(); i <i1; i++)
{
String item = originalItems.get(i);
if(item.toString().toLowerCase().contains(constraint))
suggestionItems.add(item);
}
FilterResults filterResults = new FilterResults();
filterResults.values = suggestionItems;
filterResults.count = suggestionItems.size();
return filterResults;
}
else
{
return new FilterResults();
}
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if(results !=null && results.count > 0)
{
items.clear();
items = (ArrayList<String>)results.values;
notifyDataSetChanged();
}
else
{
items.addAll(originalItems);
}
}
}
Any help would be highly appreciated.
回答1:
In Constructor no need to use add all , you can assign like this and create one more in adapter ,
List<String> suggestionItems = null;
//constructor should be like this
this.items = new ArrayList<>(objects);
this.originalItems = new ArrayList<>(objects);
this.suggestionItems = new ArrayList<>();
and filter should be
class MyFilters extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null)
{
suggestionItems .clear();
for (int i = 0, l = originalItems.size(); i < l; i++) {
String item = originalItems.get(i);
if (item.toString().toLowerCase().contains(constraint))
suggestionItems .add(item);
}
FilterResults filterResults = new FilterResults();
filterResults.values = suggestionItems ;
filterResults.count = suggestionItems .size();
return filterResults;
}
else
{
return new FilterResults();
}
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
items.clear();
items = (ArrayList<String>) results.values;
notifyDataSetChanged();
}
else {
items .addAll(originalItems );
}
}
}
来源:https://stackoverflow.com/questions/47034523/autocompletetextview-with-custom-adapter-filtering-not-working