Как использовать AutoCompleteTextView и заполнить его данными из веб-API?
Я хочу использовать AutoCompleteTextView
в моей деятельности и заполнить данные, как пользователь вводит путем запроса веб-API. Как мне это сделать?
создать новый класс и переопределить AutoCompleteTextView.performFiltering
, или я использую пользовательский адаптер списка и предоставляю пользовательский android.widget.Filter
что переопределяет performFiltering?
или есть лучший способ получить мою конечную цель?
Я сделал что-то похожее, но это было для быстрого поиска, и он включал реализацию услугу, но я считаю, что это не то, что я хочу сделать здесь.
3 ответа:
Я придумал решение, я не знаю, если это лучшее решение, но это, кажется, работает очень хорошо. То, что я сделал, был создан пользовательский адаптер, который расширяет ArrayAdapter. В пользовательском адаптере я переопределил getFilter и создал свой собственный класс фильтра, который переопределяет performFiltering. Это запускает новый поток, поэтому он не прерывает пользовательский интерфейс. Ниже приведен пример barebones.
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; } }
расширения AJ.ответ выше, следующий пользовательский адаптер включает в себя обработку запросов сервера и разбор json, а также:
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); } }
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; }