作者:蔡林荣_597 | 来源:互联网 | 2023-05-25 11:08
我使用的AutoCompleteTextView有点像这样:
public class MainActivity extends Activity {
private AutoCompleteTextView actv;
private MultiAutoCompleteTextView mactv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] countries = getResources().
getStringArray(R.array.list_of_countries);
ArrayAdapter adapter = new ArrayAdapter
(this,android.R.layout.simple_list_item_1,countries);
actv = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1);
mactv = (MultiAutoCompleteTextView) findViewById
(R.id.multiAutoCompleteTextView1);
actv.setAdapter(adapter);
mactv.setAdapter(adapter);
mactv.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
这完成了大部分工作.但是,在我的情况下,我需要自动完成,以在返回的下拉菜单建议的底部显示类似"自定义..."的内容.
所以,如果有自动填充建议,他们会显示,然后是"自定义..."建议.如果没有任何建议,它仍会显示一个建议'自定义...'.我还需要一个点击监听器'定制......'.
1> sled..:
有趣的问题,我试了一下,并基于ArrayAdapter源代码实现了一个简单的自定义适配器.
为了简洁起见,我省略了大部分未使用的代码和注释,所以如果你不确定 - 看看我上面链接的ArrayAdapter的源代码,那么评论很好.
操作原理非常简单,getCount()
适配器将一个元素添加到实际数量中.此外,getItem(int position)
将检查是否请求了最后一个"虚拟"项目,然后将返回"自定义..."字符串.
该createViewFromResource(...)
方法还检查它是否将显示最后一个"虚拟"项,如果是,它将绑定onClick侦听器.
覆盖的过滤器还会为结果计数添加一个,以使AutoCompleteView相信存在匹配,从而使下拉列表保持打开状态.
MainActivity.java
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] countries = new String[]{
"Switzerland", "Mexico", "Poland", "United States of Murica"};
// the footer item's text
String footerText = "Custom Footer....";
// our custom adapter with the custom footer text as last parameter
CustomAutoCompleteAdapter adapter = new CustomAutoCompleteAdapter(
this, android.R.layout.simple_list_item_1, countries, footerText);
// bind to our custom click listener interface
adapter.setOnFooterClickListener(new CustomAutoCompleteAdapter.OnFooterClickListener() {
@Override
public void onFooterClicked() {
// your custom item has been clicked, make some toast
Toast toast = Toast.makeText(getApplicationContext(), "Yummy Toast!", Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
});
// find auto complete text view
AutoCompleteTextView actv = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1);
actv.setThreshold(0);
actv.setAdapter(adapter);
}
}
CustomAutoCompleteAdapter.java
public class CustomAutoCompleteAdapter extends BaseAdapter implements Filterable {
public interface OnFooterClickListener {
public void onFooterClicked();
}
private List mObjects;
private final Object mLock = new Object();
private int mResource;
private int mDropDownResource;
private ArrayList mOriginalValues;
private ArrayFilter mFilter;
private LayoutInflater mInflater;
// the last item, i.e the footer
private String mFooterText;
// our listener
private OnFooterClickListener mListener;
public CustomAutoCompleteAdapter(Context context, int resource, String[] objects, String footerText) {
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mResource = mDropDownResource = resource;
mObjects = Arrays.asList(objects);
mFooterText = footerText;
}
/**
* Set listener for clicks on the footer item
*/
public void setOnFooterClickListener(OnFooterClickListener listener) {
mListener = listener;
}
@Override
public int getCount() {
return mObjects.size()+1;
}
@Override
public String getItem(int position) {
if(position == (getCount()-1)) {
// last item is always the footer text
return mFooterText;
}
// return real text
return mObjects.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return createViewFromResource(position, convertView, parent, mResource);
}
private View createViewFromResource(int position, View convertView, ViewGroup parent,
int resource) {
View view;
TextView text;
if (cOnvertView== null) {
view = mInflater.inflate(resource, parent, false);
} else {
view = convertView;
}
try {
// If no custom field is assigned, assume the whole resource is a TextView
text = (TextView) view;
} catch (ClassCastException e) {
Log.e("CustomAutoCompleteAdapter", "Layout XML file is not a text field");
throw new IllegalStateException("Layout XML file is not a text field", e);
}
text.setText(getItem(position));
if(position == (getCount()-1)) {
// it's the last item, bind click listener
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mListener != null) {
mListener.onFooterClicked();
}
}
});
} else {
// it's a real item, set click listener to null and reset to original state
view.setOnClickListener(null);
view.setClickable(false);
}
return view;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return createViewFromResource(position, convertView, parent, mDropDownResource);
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ArrayFilter();
}
return mFilter;
}
/**
* An array filter constrains the content of the array adapter with
* a prefix. Each item that does not start with the supplied prefix
* is removed from the list.
*/
private class ArrayFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence prefix) {
FilterResults results = new FilterResults();
if (mOriginalValues == null) {
synchronized (mLock) {
mOriginalValues = new ArrayList(mObjects);
}
}
if (prefix == null || prefix.length() == 0) {
ArrayList list;
synchronized (mLock) {
list = new ArrayList(mOriginalValues);
}
results.values = list;
// add +1 since we have a footer item which is always visible
results.count = list.size()+1;
} else {
String prefixString = prefix.toString().toLowerCase();
ArrayList values;
synchronized (mLock) {
values = new ArrayList(mOriginalValues);
}
final int count = values.size();
final ArrayList newValues = new ArrayList();
for (int i = 0; i ) results.values;
notifyDataSetChanged();
}
}
}
布局/ activity_main.xml中