har*_*ash 3 android textview android-activity
我使用的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;
}
}
Run Code Online (Sandbox Code Playgroud)
这完成了大部分工作.但是,在我的情况下,我需要自动完成,以在返回的下拉菜单建议的底部显示类似"自定义..."的内容.
所以,如果有自动填充建议,他们会显示,然后是"自定义..."建议.如果没有任何建议,它仍会显示一个建议'自定义...'.我还需要一个点击监听器'定制......'.
有趣的问题,我试了一下,并基于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);
}
}
Run Code Online (Sandbox Code Playgroud)
CustomAutoCompleteAdapter.java
public class CustomAutoCompleteAdapter extends BaseAdapter implements Filterable {
public interface OnFooterClickListener {
public void onFooterClicked();
}
private List<String> mObjects;
private final Object mLock = new Object();
private int mResource;
private int mDropDownResource;
private ArrayList<String> 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;
}
/**
* <p>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.</p>
*/
private class ArrayFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence prefix) {
FilterResults results = new FilterResults();
if (mOriginalValues == null) {
synchronized (mLock) {
mOriginalValues = new ArrayList<String>(mObjects);
}
}
if (prefix == null || prefix.length() == 0) {
ArrayList<String> list;
synchronized (mLock) {
list = new ArrayList<String>(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<String> values;
synchronized (mLock) {
values = new ArrayList<String>(mOriginalValues);
}
final int count = values.size();
final ArrayList<String> newValues = new ArrayList<String>();
for (int i = 0; i < count; i++) {
final String value = values.get(i);
final String valueText = value.toString().toLowerCase();
// First match against the whole, non-splitted value
if (valueText.startsWith(prefixString)) {
newValues.add(value);
} else {
final String[] words = valueText.split(" ");
final int wordCount = words.length;
// Start at index 0, in case valueText starts with space(s)
for (int k = 0; k < wordCount; k++) {
if (words[k].startsWith(prefixString)) {
newValues.add(value);
break;
}
}
}
}
results.values = newValues;
// add one since we always show the footer
results.count = newValues.size()+1;
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
//noinspection unchecked
mObjects = (List<String>) results.values;
notifyDataSetChanged();
}
}
}
Run Code Online (Sandbox Code Playgroud)
布局/ activity_main.xml中
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp"
tools:context=".MainActivity">
<AutoCompleteTextView
android:id="@+id/autoCompleteTextView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

| 归档时间: |
|
| 查看次数: |
1880 次 |
| 最近记录: |