带有自定义适配器过滤功能的 AutoCompleteTextView 不起作用 [英] AutoCompleteTextView with Custom Adapter filtering not working
问题描述
我的 android 项目中有一个 autocomplete text view
,它运行良好,但只有在其中输入第一个值时才有效.因此,为了使其更具可定制性,我添加了以下类
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());
}
});
在上面的代码中 smartMsnSpinner
是我的自动完成文本视图
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.
更新 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);
}
}
}
任何帮助将不胜感激.
推荐答案
在Constructor中不需要使用add all,你可以像这样分配并在adapter中再创建一个,
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<>();
和过滤器应该是
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 );
}
}
}
这篇关于带有自定义适配器过滤功能的 AutoCompleteTextView 不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!