如何使用AutoCompleteTextView并使用来自Web API的数据填充它?
我想在我的活动中使用一个AutoCompleteTextView
,并通过查询一个Web API来填充用户types的数据。 我怎么去做这个?
我是否创build一个新的类并重写AutoCompleteTextView.performFiltering
,或者是否使用自定义列表适配器并提供覆盖performFiltering的自定义android.widget.Filter
?
还是有更好的方法来获得我的最终目标?
我做了一些有点类似的事情,但这是为了快速search框,它涉及到实现一个服务,但我相信这不是我想要做的。
我想出了一个解决scheme,我不知道这是否是最好的解决scheme,但它似乎工作得很好。 我所做的是创build了一个扩展ArrayAdapter的自定义适配器。 在自定义适配器中,我覆盖了getFilter并创build了自己的Filter类来覆盖performFiltering。 这将启动一个新的线程,所以它不会中断用户界面。 下面是一个准系统的例子。
MyActivity.java
public class MyActivity extends Activity { private AutoCompleteTextView style; @Override public void onCreate(Bundle savedInstanceState) { ... style = (AutoCompleteTextView) findViewById(R.id.style); adapter = new AutoCompleteAdapter(this, android.R.layout.simple_dropdown_item_1line); style.setAdapter(adapter); } }
AutoCompleteAdapter.java
public class AutoCompleteAdapter extends ArrayAdapter<Style> implements Filterable { private ArrayList<Style> mData; public AutoCompleteAdapter(Context context, int textViewResourceId) { super(context, textViewResourceId); mData = new ArrayList<Style>(); } @Override public int getCount() { return mData.size(); } @Override public Style getItem(int index) { return mData.get(index); } @Override public Filter getFilter() { Filter myFilter = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults filterResults = new FilterResults(); if(constraint != null) { // A class that queries a web API, parses the data and returns an ArrayList<Style> StyleFetcher fetcher = new StyleFetcher(); try { mData = fetcher.retrieveResults(constraint.toString()); } catch(Exception e) { Log.e("myException", e.getMessage()); } // Now assign the values and count to the FilterResults object filterResults.values = mData; filterResults.count = mData.size(); } return filterResults; } @Override protected void publishResults(CharSequence contraint, FilterResults results) { if(results != null && results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } }; return myFilter; } }
Chu:要自定义视图的外观并获得对展开对象的更多控制,请执行以下操作:
@Override public View getView (int position, View convertView, ViewGroup parent) { TextView originalView = (TextView) super.getView(position, convertView, parent); // Get the original view final LayoutInflater inflater = LayoutInflater.from(getContext()); final TextView view = (TextView) inflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false); // Start tweaking view.setText(originalView.getText()); view.setTextColor(R.color.black); // also useful if you have a color scheme that makes the text show up white view.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10); // override the text size return view; }
扩大AJ。 上面的答案,下面的自定义适配器包括处理服务器请求和jsonparsing:
class AutoCompleteAdapter extends ArrayAdapter<String> implements Filterable { private ArrayList<String> data; private final String server = "http://myserver/script.php?query="; AutoCompleteAdapter (@NonNull Context context, @LayoutRes int resource) { super (context, resource); this.data = new ArrayList<>(); } @Override public int getCount() { return data.size(); } @Nullable @Override public String getItem (int position) { return data.get (position); } @NonNull @Override public Filter getFilter() { return new Filter() { @Override protected FilterResults performFiltering (CharSequence constraint) { FilterResults results = new FilterResults(); if (constraint != null) { HttpURLConnection conn = null; InputStream input = null; try { URL url = new URL (server + constraint.toString()); conn = (HttpURLConnection) url.openConnection(); input = conn.getInputStream(); InputStreamReader reader = new InputStreamReader (input, "UTF-8"); BufferedReader buffer = new BufferedReader (reader, 8192); StringBuilder builder = new StringBuilder(); String line; while ((line = buffer.readLine()) != null) { builder.append (line); } JSONArray terms = new JSONArray (builder.toString()); ArrayList<String> suggestions = new ArrayList<>(); for (int ind = 0; ind < terms.length(); ind++) { String term = terms.getString (ind); suggestions.add (term); } results.values = suggestions; results.count = suggestions.size(); data = suggestions; } catch (Exception ex) { ex.printStackTrace(); } finally { if (input != null) { try { input.close(); } catch (Exception ex) { ex.printStackTrace(); } } if (conn != null) conn.disconnect(); } } return results; } @Override protected void publishResults (CharSequence constraint, FilterResults results) { if (results != null && results.count > 0) { notifyDataSetChanged(); } else notifyDataSetInvalidated(); } }; }
并以相同的方式使用它:
public class MyActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { ... AutoCompleteTextView textView = (AutoCompleteTextView) findViewById (R.id.style); int layout = android.R.layout.simple_list_item_1; AutoCompleteAdapter adapter = new AutoCompleteAdapter (this, layout); textView.setAdapter (adapter); } }