2012-07-01 18 views
9

Hay un momento en mi aplicación, que necesito forzar para mostrar todos los elementos en la lista de sugerencias, sin importar lo que haya escrito el usuario. ¿Cómo puedo hacer eso?AutoCompleteTextView forzar para mostrar todos los elementos

Intenté hacer algo con el filtrado, pero para mí, como principiante, el filtrado es demasiado complicado, intenté buscar tutorial para principiantes para filtrar sin ningún tipo de suerte. Tal vez, hay una forma más simple de obligar a mostrar todos los elementos de sugerencia?

EDITAR: Básicamente lo que fue mi idea, es que, cuando el usuario escribe algo que no está en la lista, muestra todas las opciones disponibles que puede tener.

He encontrado la mejor manera de verificar si se muestra o no el ACTV, pero enTextChangeEvent comparo el texto escrito por el usuario con mi lista, y luego, si no se han encontrado elementos, aparece la lista completa.

public void onTextChanged(CharSequence s, int start, int before, int count) 
     {     
      final EditText editText = (EditText) findViewById(R.id.vardsUserInput); 
      String strValue = editText.getText().toString().toUpperCase(); 
      String temp; 
      int Cc=0; //my count variable 
      for(int i=0; i<vardi.length; i++) 
      { 
       temp = vardi[i].toUpperCase(); 
       if(temp.startsWith(strValue.toUpperCase())) 
       { 
        Log.d("testing",vardi[i]); 
        Cc++;             
       } 
      }    
     if(Cc == 0) 
     { 
     //Show all the available options 
    textView.showDropDown();      
     }     
} 

Respuesta

8

Básicamente, después de 5-6 horas de experimentación para entender cómo funciona el filtro de maldición, escribí mi propio adaptador que hace exactamente lo que quiero:

public class burtuAdapteris extends ArrayAdapter<String> implements Filterable { 

     ArrayList<String> _items = new ArrayList<String>(); 
     ArrayList<String> orig = new ArrayList<String>(); 

     public burtuAdapteris(Context context, int resource, ArrayList<String> items) { 
      super(context, resource, items);  

      for (int i = 0; i < items.size(); i++) { 
       orig.add(items.get(i)); 
      } 
     } 

     @Override 
     public int getCount() { 
      if (_items != null) 
       return _items.size(); 
      else 
       return 0; 
     } 

     @Override 
     public String getItem(int arg0) { 
      return _items.get(arg0); 
     } 


     @Override 

     public Filter getFilter() { 
      Filter filter = new Filter() { 
       @Override 
       protected FilterResults performFiltering(CharSequence constraint) { 

        if(constraint != null) 
         Log.d("Constraints", constraint.toString()); 
        FilterResults oReturn = new FilterResults(); 

       /* if (orig == null){ 
        for (int i = 0; i < items.size(); i++) { 
         orig.add(items.get(i)); 
        } 
        }*/ 
        String temp; 
        int counters = 0; 
        if (constraint != null){ 

         _items.clear(); 
         if (orig != null && orig.size() > 0) { 
          for(int i=0; i<orig.size(); i++) 
          {       
           temp = orig.get(i).toUpperCase(); 

           if(temp.startsWith(constraint.toString().toUpperCase())) 
           { 

            _items.add(orig.get(i));    
counters++; 

           } 
          } 
         } 
         Log.d("REsult size:" , String.valueOf(_items.size())); 
          if(!counters) 
          { 
          _items.clear(); 
          _items = orig; 
          } 
         oReturn.values = _items; 
         oReturn.count = _items.size(); 
        } 
        return oReturn; 
       } 


       @SuppressWarnings("unchecked") 
       @Override 
       protected void publishResults(CharSequence constraint, FilterResults results) { 
        if(results != null && results.count > 0) { 
         notifyDataSetChanged(); 
         } 
         else { 
          notifyDataSetInvalidated(); 
         } 

       } 

      }; 

      return filter; 

     } 


} 

Y que es fácil de usar, basta con sustituir el adaptador original con esto:

final burtuAdapteris fAdapter = new burtuAdapteris(this, android.R.layout.simple_dropdown_item_1line, liste); 

En mi caso es la liste: ArrayList<String> liste = new ArrayList<String>();

+2

Estoy copiando y pegando, pero dejando el nombre de BurtuAdapter en homenaje a su trabajo. :) – brainmurphy1

11

No define el "momento" cuando desea mostrar todos los resultados, así que espero que esto encaje. Pero trata de algo como esto:

AutoCompleteTextView autoComplete; 
String savedText; 

public void showAll() { 
    savedText = autoComplete.getText().toString(); 
    autoComplete.setText(""); 
    autoComplete.showDropDown(); 
} 

public void restore() { 
    autoComplete.setText(savedText); 
} 
+1

Cuando probé este instante me dieron "Desafortunadamente, esta aplicación se ha detenido " No entendí realmente dónde debería usar la función restaurar. – XCoder

+0

Ok, entonces necesito un contexto para su pregunta. Por favor, publique el código relevante que ha escrito en su pregunta y describa el momento en que desea mostrar todo. – Sam

+0

He editado, y traté de explicar con más precisión qué Im después de – XCoder

-1

En realidad es incluso más fácil que Sam en la lista. Cada vez que desee mostrar todos, acaba de hacer:

performFiltering("", 0); 

Cuando termina la filtración, se mostrará automáticamente el menú desplegable con todos los elementos visibles.

+0

¿Podría por favor proporcionar un poco más de contexto? performFiltering() es un método protegido de la clase [Filter] (http://developer.android.com/reference/android/widget/Filter.html). Parece que necesito subclasificar el filtro para tenerlo en mis manos. – ge0rg

+0

Ya no trabajo para la empresa en la que estaba cuando escribí eso, y no he tocado Android desde que los dejé en diciembre, así que desafortunadamente ya no tengo acceso a ese código en contexto. Lo siento. – ArtOfWarfare

2

método mostrar la lista desplegable.

necesita llamar a requestFocus(); para mostrar el teclado, de lo contrario el teclado no aparece.

autocomptv.setOnTouchListener(new OnTouchListener() { 

     @SuppressLint("ClickableViewAccessibility") 
     @Override 
     public boolean onTouch(View paramView, MotionEvent paramMotionEvent) { 
      // TODO Auto-generated method stub 
      autocomptv.showDropDown(); 
      autocomptv.requestFocus(); 
      return false; 
     } 
    }); 
1

Esto funciona para mí perfectamente, esta es una manera fácil de resolver el problema:

final ArrayAdapter<String> adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_dropdown_item_1line, usernameLists); 
    etUsername.setThreshold(1); 
    etUsername.setAdapter(adapter); 
    etUsername.setOnTouchListener(new View.OnTouchListener() { 

     @SuppressLint("ClickableViewAccessibility") 
     @Override 
     public boolean onTouch(View paramView, MotionEvent paramMotionEvent) { 
      if (usernameLists.size() > 0) { 
       // show all suggestions 
       if (!etUsername.getText().toString().equals("")) 
        adapter.getFilter().filter(null); 
       etUsername.showDropDown(); 
      } 
      return false; 
     } 
    }); 
+0

Lol mucho más corto y más simple que las otras soluciones, hace el trabajo, usando AutoCompleteTextView en lugar de ese maldito Spinner, con esto puedo establecer sugerencias y errores y nunca tener que usar ese spinner de nuevo, gracias :) – user3718908

+0

Usé OnClickListener sin embargo, y establecer la propiedad enfocable en falso. – user3718908

0

Como "ArtOfWarfare" sugerido, puede simplemente subclase y anular performFiltering():

public class My_AutoCompleteTextView extends AutoCompleteTextView { 
    public My_AutoCompleteTextView(Context context) { 
     super(context); 
    } 
    public My_AutoCompleteTextView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 
    public My_AutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @Override 
    protected void performFiltering(CharSequence text, int keyCode) { 
     super.performFiltering("", 0); 
    } 
} 
1

Si desea mostrar las sugerencias al instante, debe anular enoughToFilter() para que siempre devuelva verdadero. Para ignorar lo que se da como entrada de texto, debe usar performFiltering("", 0) con un patrón de filtrado vacío. El AutoCompleteTextView muestra todas las sugerencias.

Esta es la solución He combinado de otros mensajes StackOverflow:

public class InstantAutoComplete extends android.support.v7.widget.AppCompatAutoCompleteTextView { 
    public InstantAutoComplete(Context context) { 
     super(context); 
    } 

    public InstantAutoComplete(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public InstantAutoComplete(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @Override 
    public boolean enoughToFilter() { 
     return true; 
    } 

    @Override 
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { 
     super.onFocusChanged(focused, direction, previouslyFocusedRect); 

     if (focused && getAdapter() != null) { 
      performFiltering("", 0); 
     } 
    } 
} 
0

Esto es lo que funcionó para mí:

public class CustomAutoCompleteTextView extends AutoCompleteTextView { 
    public CustomAutoCompleteTextView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    public boolean enoughToFilter() { 
     return true; 
    } 

    @Override 
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { 
     super.onFocusChanged(focused, direction, previouslyFocusedRect); 
     if (focused) { 
      performFiltering(getText(), 0); 
     } 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     this.showDropDown(); 
     return super.onTouchEvent(event); 
    } 
} 
Cuestiones relacionadas