Obtener las sugerencias de AutoCompleteTextView del servicio en un hilo independiente
Para mi AutoCompleteTextView
necesito buscar los datos de un webservice. Como puede tomar un poco de tiempo no quiero que el hilo de la interfaz de usuario no responda, por lo que necesito de alguna manera para obtener los datos en un hilo separado. Por ejemplo, al obtener datos de la base de datos SQLite, es muy fácil hacerlo con el método CursorAdapter
– runQueryOnBackgroundThread
. Estaba buscando a otros adaptadores como ArrayAdapter
, BaseAdapter
, pero no podía encontrar nada similar …
¿Hay una manera fácil de lograr esto? No puedo simplemente usar ArrayAdapter
directamente, ya que la lista de sugerencias es dinámica. Siempre busco la lista de sugerencias dependiendo de la entrada del usuario, por lo que no se puede pre-extraer y almacenar en caché para uso posterior.
- Cómo esperar a que Android runOnUiThread para ser terminado?
- Android - Async Tarea de comportamiento en 2.3.3 y 4.0 OS
- Descargar el archivo hace que la interfaz de usuario gague
- ¿Por qué no se detiene el hilo?
- Cómo y reiniciar el hilo de nuevo en la actividad creada
Si alguien podría dar algunos consejos o ejemplos sobre este tema – sería genial!
- ¿Es seguro usar Java Threads de la misma manera que las aplicaciones de escritorio?
- Manera eficiente de manipular los subprocesos RxJava
- Android: "Actualizar automáticamente" después de un tiempo determinado
- ¿Algún consejo sobre cómo acelerar esto en Android?
- Enhebrado en Android
- ¿Cuál es la diferencia entre Handler, Runnable y Threads?
- Cómo comprobar si el hilo actual no es el hilo principal
- Acceso a vistas desde otro hilo (Android)
Con el enfoque anterior, también tenía esos problemas al escribir muy rápido. Supongo que es porque el filtrado de los resultados se realiza asincrónicamente por la clase de filtro, por lo que puede haber problemas al modificar ArrayList del adaptador en el hilo ui mientras se realiza el filtrado.
http://developer.android.com/reference/android/widget/Filter.html
Sin embargo, con el siguiente enfoque todo funcionó bien.
public class MyActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); MyAdapter myAdapter = new MyAdapter(this, android.R.layout.simple_dropdown_item_1line); AutoCompleteTextView acTextView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1); acTextView.setAdapter(myAdapter); } } public class MyAdapter extends ArrayAdapter<MyObject> { private Filter mFilter; private List<MyObject> mSubData = new ArrayList<MyObject>(); static int counter=0; public MyAdapter(Context context, int textViewResourceId) { super(context, textViewResourceId); setNotifyOnChange(false); mFilter = new Filter() { private int c = ++counter; private List<MyObject> mData = new ArrayList<MyObject>(); @Override protected FilterResults performFiltering(CharSequence constraint) { // This method is called in a worker thread mData.clear(); FilterResults filterResults = new FilterResults(); if(constraint != null) { try { // Here is the method (synchronous) that fetches the data // from the server URL url = new URL("..."); URLConnection conn = url.openConnection(); BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line = ""; while ((line = rd.readLine()) != null) { mData.add(new MyObject(line)); } } catch(Exception e) { } filterResults.values = mData; filterResults.count = mData.size(); } return filterResults; } @SuppressWarnings("unchecked") @Override protected void publishResults(CharSequence contraint, FilterResults results) { if(c == counter) { mSubData.clear(); if(results != null && results.count > 0) { ArrayList<MyObject> objects = (ArrayList<MyObject>)results.values; for (MyObject v : objects) mSubData.add(v); notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } } }; } @Override public int getCount() { return mSubData.size(); } @Override public MyObject getItem(int index) { return mSubData.get(index); } @Override public Filter getFilter() { return mFilter; } }
EDITADO: Se agregó una forma ingenua de evitar que se muestre la lista desplegable al hacer clic en una sugerencia.
Hago algo como esto en mi aplicación:
private AutoCompleteTextView mSearchbar; private ArrayAdapter<String> mAutoCompleteAdapter; @Override protected void onCreate(Bundle savedInstanceState) { mAutoCompleteAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line); mSearchbar = (AutoCompleteTextView) findViewById(R.id.searchbar); mSearchbar.setThreshold(3); mSearchbar.setAdapter(mAutoCompleteAdapter); mSearchbar.addTextChangedListener(new TextWatcher() { private boolean shouldAutoComplete = true; @Override public void onTextChanged(CharSequence s, int start, int before, int count) { shouldAutoComplete = true; for (int position = 0; position < mAutoCompleteAdapter.getCount(); position++) { if (mAutoCompleteAdapter.getItem(position).equalsIgnoreCase(s.toString())) { shouldAutoComplete = false; break; } } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { if (shouldAutoComplete) { new DoAutoCompleteSearch().execute(s.toString()); } } } } private class DoAutoCompleteSearch extends AsyncTask<String, Void, ArrayList<String>> { @Override protected ArrayList<String> doInBackground(String... params) { ArrayList<String> autoComplete = new ArrayList<String>(); //do autocomplete search and stuff. return autoComplete; } @Override protected void onPostExecute(ArrayList<String> result) { mAutoCompleteAdapter.clear(); for (String s : result) mAutoCompleteAdapter.add(s); } }
Tenía la misma solución, excepto que el problema es que todo está bien (las variables se actualizan cuando depura), pero el autocompletar se llena extrañamente como en
Cuando escriba sco tiene los resultados, pero no se muestra en la lista, pero cuando backspace i muestra el resultado de sco. En depuración todas las variables se actualizan, que sólo me dice que la interfaz de usuario no se está actualizando para AutoCompleteTextView. Como cuando backspace i se dispara para actualizar y luego muestra la lista de computadoras anteriores y luego (en el tiempo que lo actualiza con los nuevos elementos de la lista para la nueva cadena de búsqueda. Nadie se encontró con este problema?
- Android M crash java.lang.UnsatisfiedLinkError: dlopen falló:
- ¿Cómo cambiar el color de fondo de la tecla para el teclado suave android?