Android 带有自定义适配器的 AutoCompleteTextView
Android AutoCompleteTextView with custom Adapter
我陷入了与此非常相似的情况:Android: Using item selected in AutoCompleteTextView to populate another field
在 SO 阅读了这么多帖子和答案后,我已经设法达到了 AutoCompleteTextView 使用自定义 XML 填充客户列表(我需要的自定义对象/POJO)的地步布局,但我收到此错误,这似乎是由于索引逻辑引起的:
java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.get(ArrayList.java:437)
at irisdesigns.studio.jewellery.Model.CustomerAutoAdapter.getView(CustomerAutoAdapter.java:76)
at android.widget.AbsListView.obtainView(AbsListView.java:2365)
at android.widget.DropDownListView.obtainView(DropDownListView.java:305)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1408)
at android.widget.ListPopupWindow.buildDropDown(ListPopupWindow.java:1257)
at android.widget.ListPopupWindow.show(ListPopupWindow.java:613)
at android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1217)
at android.widget.AutoCompleteTextView.updateDropDownForFilter(AutoCompleteTextView.java:1086)
at android.widget.AutoCompleteTextView.onFilterComplete(AutoCompleteTextView.java:1068)
at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:285)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
有人可以帮忙吗?
适配器代码:
public class CustomerAutoAdapter extends ArrayAdapter implements Filterable {
private ArrayList<CustomerSuggestion> customerSuggestions, filteredList;
public CustomerAutoAdapter(Context context, ArrayList<CustomerSuggestion> customerSuggestions) {
super(context, 0, customerSuggestions);
this.customerSuggestions = customerSuggestions;
this.filteredList = customerSuggestions;
}
@Nullable
@Override
public CustomerSuggestion getItem(int position) {
return customerSuggestions.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (convertView == null) {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.litem_customer_autocomplete, parent, false);
}
CustomerSuggestion customerSuggestion = filteredList.get(position);
if (customerSuggestion != null) {
((TextView) view.findViewById(R.id.tv_cust_auto_name)).setText(customerSuggestion.getCustomer().getName());
((TextView) view.findViewById(R.id.tv_cust_auto_ph)).setText(customerSuggestion.getCustomer().getPh1());
((TextView) view.findViewById(R.id.tv_cust_auto_email)).setText(customerSuggestion.getCustomer().getEmail());
}
return view;
}
@Override
public Filter getFilter() {
return filter;
}
// Custom Filter implementation for custom suggestions we provide.
private Filter filter = new Filter() {
@Override
public CharSequence convertResultToString(Object resultValue) {
return ((CustomerSuggestion) resultValue).getCustomer().getName();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null && constraint.length()>1) {
ArrayList<CustomerSuggestion> filteredList = new ArrayList<>();
for (CustomerSuggestion customerSuggestion : customerSuggestions)
if (customerSuggestion.getCustomer().getName().toLowerCase().contains(constraint.toString().toLowerCase()))
filteredList.add(customerSuggestion);
FilterResults filterResults = new FilterResults();
filterResults.values = filteredList;
filterResults.count = filteredList.size();
return filterResults;
} else
return new FilterResults();
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
filteredList = (ArrayList<CustomerSuggestion>) results.values;
notifyDataSetChanged();
}
else
filteredList = customerSuggestions;
}
};
}
MainActivity 代码: Text Watched 和 setAdapter
final CustomerAutoAdapter customerAutoAdapter = new CustomerAutoAdapter(getApplicationContext(),customerSuggestions);
et_customer_name.setAdapter(customerAutoAdapter);
et_customer_name.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
// you can use runnable postDelayed like 500 ms to delay search text
cust_key = "";
if (userExists) {
et_phone1.setText("");
et_cc_phone1.setText("+91");
et_phone2.setText("");
et_cc_phone2.setText("");
et_email.setText("");
tv_btn_od_create_phone.setText("+ Phone");
et_phone1.setEnabled(true);
et_cc_phone1.setEnabled(true);
et_phone2.setEnabled(true);
et_cc_phone2.setEnabled(true);
et_email.setEnabled(true);
tv_btn_od_create_phone.setEnabled(true);
tv_btn_od_create_phone.setVisibility(View.VISIBLE);
et_phone2.setVisibility(View.GONE);
et_cc_phone2.setVisibility(View.GONE);
}
userExists = false;
// customerAutoAdapter.filter(et_customer_name.getText().toString());
}
});
AutoCompleteTextView setOnClickListener:
et_customer_name.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
cust_key = customerSuggestions.get(position).getCust_key();
autoFillData(position);
userExists = true;
}
});
在这一行
CustomerSuggestion customerSuggestion = filteredList.get(position);
尝试使用原始列表而不是过滤后的列表,如下所示。
CustomerSuggestion customerSuggestion = customerSuggestions.get(position);
经过一番查找,我认为是因为这种适配器的主列表是原始列表而不是过滤后的列表,所以调用获取视图方法是指原始列表!
我陷入了与此非常相似的情况:Android: Using item selected in AutoCompleteTextView to populate another field
在 SO 阅读了这么多帖子和答案后,我已经设法达到了 AutoCompleteTextView 使用自定义 XML 填充客户列表(我需要的自定义对象/POJO)的地步布局,但我收到此错误,这似乎是由于索引逻辑引起的:
java.lang.IndexOutOfBoundsException: Index: 2, Size: 2 at java.util.ArrayList.get(ArrayList.java:437) at irisdesigns.studio.jewellery.Model.CustomerAutoAdapter.getView(CustomerAutoAdapter.java:76) at android.widget.AbsListView.obtainView(AbsListView.java:2365) at android.widget.DropDownListView.obtainView(DropDownListView.java:305) at android.widget.ListView.measureHeightOfChildren(ListView.java:1408) at android.widget.ListPopupWindow.buildDropDown(ListPopupWindow.java:1257) at android.widget.ListPopupWindow.show(ListPopupWindow.java:613) at android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1217) at android.widget.AutoCompleteTextView.updateDropDownForFilter(AutoCompleteTextView.java:1086) at android.widget.AutoCompleteTextView.onFilterComplete(AutoCompleteTextView.java:1068) at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:285) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
有人可以帮忙吗? 适配器代码:
public class CustomerAutoAdapter extends ArrayAdapter implements Filterable {
private ArrayList<CustomerSuggestion> customerSuggestions, filteredList;
public CustomerAutoAdapter(Context context, ArrayList<CustomerSuggestion> customerSuggestions) {
super(context, 0, customerSuggestions);
this.customerSuggestions = customerSuggestions;
this.filteredList = customerSuggestions;
}
@Nullable
@Override
public CustomerSuggestion getItem(int position) {
return customerSuggestions.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (convertView == null) {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.litem_customer_autocomplete, parent, false);
}
CustomerSuggestion customerSuggestion = filteredList.get(position);
if (customerSuggestion != null) {
((TextView) view.findViewById(R.id.tv_cust_auto_name)).setText(customerSuggestion.getCustomer().getName());
((TextView) view.findViewById(R.id.tv_cust_auto_ph)).setText(customerSuggestion.getCustomer().getPh1());
((TextView) view.findViewById(R.id.tv_cust_auto_email)).setText(customerSuggestion.getCustomer().getEmail());
}
return view;
}
@Override
public Filter getFilter() {
return filter;
}
// Custom Filter implementation for custom suggestions we provide.
private Filter filter = new Filter() {
@Override
public CharSequence convertResultToString(Object resultValue) {
return ((CustomerSuggestion) resultValue).getCustomer().getName();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
if (constraint != null && constraint.length()>1) {
ArrayList<CustomerSuggestion> filteredList = new ArrayList<>();
for (CustomerSuggestion customerSuggestion : customerSuggestions)
if (customerSuggestion.getCustomer().getName().toLowerCase().contains(constraint.toString().toLowerCase()))
filteredList.add(customerSuggestion);
FilterResults filterResults = new FilterResults();
filterResults.values = filteredList;
filterResults.count = filteredList.size();
return filterResults;
} else
return new FilterResults();
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
filteredList = (ArrayList<CustomerSuggestion>) results.values;
notifyDataSetChanged();
}
else
filteredList = customerSuggestions;
}
};
}
MainActivity 代码: Text Watched 和 setAdapter
final CustomerAutoAdapter customerAutoAdapter = new CustomerAutoAdapter(getApplicationContext(),customerSuggestions);
et_customer_name.setAdapter(customerAutoAdapter);
et_customer_name.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
// you can use runnable postDelayed like 500 ms to delay search text
cust_key = "";
if (userExists) {
et_phone1.setText("");
et_cc_phone1.setText("+91");
et_phone2.setText("");
et_cc_phone2.setText("");
et_email.setText("");
tv_btn_od_create_phone.setText("+ Phone");
et_phone1.setEnabled(true);
et_cc_phone1.setEnabled(true);
et_phone2.setEnabled(true);
et_cc_phone2.setEnabled(true);
et_email.setEnabled(true);
tv_btn_od_create_phone.setEnabled(true);
tv_btn_od_create_phone.setVisibility(View.VISIBLE);
et_phone2.setVisibility(View.GONE);
et_cc_phone2.setVisibility(View.GONE);
}
userExists = false;
// customerAutoAdapter.filter(et_customer_name.getText().toString());
}
});
AutoCompleteTextView setOnClickListener:
et_customer_name.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
cust_key = customerSuggestions.get(position).getCust_key();
autoFillData(position);
userExists = true;
}
});
在这一行
CustomerSuggestion customerSuggestion = filteredList.get(position);
尝试使用原始列表而不是过滤后的列表,如下所示。
CustomerSuggestion customerSuggestion = customerSuggestions.get(position);
经过一番查找,我认为是因为这种适配器的主列表是原始列表而不是过滤后的列表,所以调用获取视图方法是指原始列表!