2010-06-11 13 views
53

¿Cómo puedo mostrar un combobox en Android?¿Cómo puedo mostrar un combobox en Android?

+1

Por favor explique más claramente lo que quiere. Y lo que ya has intentado. – fretje

+24

@fretje La pregunta es bastante específica. Si sabe qué es ** ComboBox **, no necesita explicación. Si no lo haces, aún puedes buscarlo en google: http://en.wikipedia.org/wiki/Combo_box – vbence

+1

@vbence: No estaba hablando del ComboBox. Como Android es un sistema operativo, también podría preguntar "Cómo mostrar un cuadro combinado en Windows", que no es específico en absoluto. – fretje

Respuesta

56

En android se llama Spinner, puedes echar un vistazo al tutorial aquí.

Hello, Spinner

Y esta es una pregunta muy vaga, usted debe tratar de ser más descriptivo de su problema.

+15

Sugiero que considere esto en el contexto de Android desarrollo. http://www.designerandroid.com/?p=8. En el Contexto de android dev se conoce como un Spinner. Por favor haz tu investigación la próxima vez. – gruntled

+0

No creo que esa fuente sea autoritativa. Por el contrario, un poco más de fuente autoritaria dice lo contrario: http://developer.android.com/guide/topics/ui/custom-components.html – vbence

+3

Sí y al mirar el sitio que ha proporcionado usted puede ver que lo hacen hacer mención a un ComboBox en esa página, pero en la API solo hay una referencia a Spinner (http://developer.android.com/resources/tutorials/views/hello-spinner.html) Aquí ellos claramente afirman que un "Spinner" es un widget similar a una lista desplegable para seleccionar elementos ". Estoy de acuerdo con usted en que esto DEBERÍA llamarse ComboBox como con otras implementaciones de Java, pero en este contexto no lo es. – gruntled

6

No probado, pero cuanto más cerca se puede obtener parece ser con AutoCompleteTextView. Puede escribir un adaptador que ignore las funciones de filtro. Algo así como:

class UnconditionalArrayAdapter<T> extends ArrayAdapter<T> { 
    final List<T> items; 
    public UnconditionalArrayAdapter(Context context, int textViewResourceId, List<T> items) { 
     super(context, textViewResourceId, items); 
     this.items = items; 
    } 

    public Filter getFilter() { 
     return new NullFilter(); 
    } 

    class NullFilter extends Filter { 
     protected Filter.FilterResults performFiltering(CharSequence constraint) { 
      final FilterResults results = new FilterResults(); 
      results.values = items; 
      return results; 
     } 

     protected void publishResults(CharSequence constraint, Filter.FilterResults results) { 
      items.clear(); // `items` must be final, thus we need to copy the elements by hand. 
      for (Object item : (List) results.values) { 
       items.add((String) item); 
      } 
      if (results.count > 0) { 
       notifyDataSetChanged(); 
      } else { 
       notifyDataSetInvalidated(); 
      } 
     } 
    } 
} 

... entonces en su onCreate:

String[] COUNTRIES = new String[] {"Belgium", "France", "Italy", "Germany"}; 
List<String> contriesList = Arrays.asList(COUNTRIES()); 
ArrayAdapter<String> adapter = new UnconditionalArrayAdapter<String>(this, 
    android.R.layout.simple_dropdown_item_1line, contriesList); 
AutoCompleteTextView textView = (AutoCompleteTextView) 
    findViewById(R.id.countries_list); 
textView.setAdapter(adapter); 

El código no se ha probado, no puede haber algunas características con el método de filtrado que no considero, pero hay que tenerlo , los principios básicos para emular un ComboBox con AutoCompleteTextView.

Editar Implementación fija de NullFilter. Necesitamos acceso a los elementos, por lo tanto, el constructor del UnconditionalArrayAdapter necesita tomar una referencia a una lista (tipo de memoria intermedia). También puede usar, p. adapter = new UnconditionalArrayAdapter<String>(..., new ArrayList<String>); y luego use adapter.add("Luxemburg"), por lo que no necesita administrar la lista de almacenamiento intermedio.

+0

Este código no se acerca a la compilación. Las llamadas a getFilter() parecen intentos en un bucle infinito, y publishResults está devolviendo un valor de un método de vacío. La idea es buena en general, pero alguien debería corregir este ejemplo. – dhakim

10

Aquí es un ejemplo de cuadro combinado costumbre en android:

package myWidgets; 
import android.content.Context; 
import android.database.Cursor; 
import android.text.InputType; 
import android.util.AttributeSet; 
import android.view.View; 
import android.widget.AutoCompleteTextView; 
import android.widget.ImageButton; 
import android.widget.LinearLayout; 
import android.widget.SimpleCursorAdapter; 

public class ComboBox extends LinearLayout { 

    private AutoCompleteTextView _text; 
    private ImageButton _button; 

    public ComboBox(Context context) { 
     super(context); 
     this.createChildControls(context); 
    } 

    public ComboBox(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     this.createChildControls(context); 
} 

private void createChildControls(Context context) { 
    this.setOrientation(HORIZONTAL); 
    this.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, 
        LayoutParams.WRAP_CONTENT)); 

    _text = new AutoCompleteTextView(context); 
    _text.setSingleLine(); 
    _text.setInputType(InputType.TYPE_CLASS_TEXT 
        | InputType.TYPE_TEXT_VARIATION_NORMAL 
        | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES 
        | InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE 
        | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); 
    _text.setRawInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD); 
    this.addView(_text, new LayoutParams(LayoutParams.WRAP_CONTENT, 
        LayoutParams.WRAP_CONTENT, 1)); 

    _button = new ImageButton(context); 
    _button.setImageResource(android.R.drawable.arrow_down_float); 
    _button.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
        _text.showDropDown(); 
      } 
    }); 
    this.addView(_button, new LayoutParams(LayoutParams.WRAP_CONTENT, 
        LayoutParams.WRAP_CONTENT)); 
} 

/** 
    * Sets the source for DDLB suggestions. 
    * Cursor MUST be managed by supplier!! 
    * @param source Source of suggestions. 
    * @param column Which column from source to show. 
    */ 
public void setSuggestionSource(Cursor source, String column) { 
    String[] from = new String[] { column }; 
    int[] to = new int[] { android.R.id.text1 }; 
    SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this.getContext(), 
        android.R.layout.simple_dropdown_item_1line, source, from, to); 
    // this is to ensure that when suggestion is selected 
    // it provides the value to the textbox 
    cursorAdapter.setStringConversionColumn(source.getColumnIndex(column)); 
    _text.setAdapter(cursorAdapter); 
} 

/** 
    * Gets the text in the combo box. 
    * 
    * @return Text. 
    */ 
public String getText() { 
    return _text.getText().toString(); 
} 

/** 
    * Sets the text in combo box. 
    */ 
public void setText(String text) { 
    _text.setText(text); 
    } 
} 

espero que ayude !!

+1

Gracias por su respuesta. Quiero usar este widget, pero quiero usar una matriz de Cadena como fuente de datos, no como cursor. ¿que debería hacer? –

0

Para un cuadro combinado (http://en.wikipedia.org/wiki/Combo_box) que permite el ingreso de texto libre y tiene un cuadro de lista desplegable Usé un AutoCompleteTextView según lo sugerido por vbence.

Utilicé el onClickListener para mostrar el cuadro de lista desplegable cuando el usuario selecciona el control.

Creo que esto se parece mejor a este tipo de combobox.

private static final String[] STUFF = new String[] { "Thing 1", "Thing 2" }; 

public void onCreate(Bundle b) { 
    final AutoCompleteTextView view = 
     (AutoCompleteTextView) findViewById(R.id.myAutoCompleteTextView); 

    view.setOnClickListener(new View.OnClickListener() 
    { 
     @Override 
     public void onClick(View v) 
     { 
       view.showDropDown(); 
     } 
    }); 

    final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
     this, 
     android.R.layout.simple_dropdown_item_1line, 
     STUFF 
    ); 
    view.setAdapter(adapter); 
} 
5

las preguntas es perfectamente válida y clara desde Spinner y ComboBox (lean: Spinner donde se puede proporcionar un valor personalizado también) son dos cosas diferentes.

Estaba buscando lo mismo y no estaba satisfecho con las respuestas dadas. Así que creé mi propia cosa. Quizás algunos encuentren útiles los siguientes consejos. No proporciono el código fuente completo ya que estoy usando algunas llamadas heredadas en mi propio proyecto. Debería estar bastante claro de todos modos.

Aquí está la captura de pantalla de la última cosa:

ComboBox on Android

El primero era crear una vista que tendrá el mismo aspecto como la ruleta que no se ha ampliado aún. En la captura de pantalla, en la parte superior de la pantalla (fuera de foco), puede ver el ruteador y la vista personalizada justo abajo. Para ese propósito, utilicé LinearLayout (en realidad, heredé de Linear Layout) con style="?android:attr/spinnerStyle".LinearLayout contiene TextView con style="?android:attr/spinnerItemStyle". Fragmento de XML completa sería:

<com.example.comboboxtest.ComboBox 
    style="?android:attr/spinnerStyle" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    > 

    <TextView 
     android:id="@+id/textView" 
     style="?android:attr/spinnerItemStyle" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:ellipsize="marquee" 
     android:singleLine="true" 
     android:text="January" 
     android:textAlignment="inherit" 
    /> 

</com.example.comboboxtest.ComboBox> 

Como, he mencionado anteriormente ComboBox hereda de LinearLayout. También implementa OnClickListener, que crea un diálogo con una vista personalizada inflada desde el archivo XML. Aquí está la visión exagerada:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical" 
    > 
    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" 
     > 
     <EditText 
      android:id="@+id/editText" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_weight="1" 
      android:ems="10" 
      android:hint="Enter custom value ..." > 

      <requestFocus /> 
     </EditText> 

     <Button 
      android:id="@+id/button" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_weight="1" 
      android:text="OK" 
     /> 
    </LinearLayout> 

    <ListView 
     android:id="@+id/listView1" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
    /> 

</LinearLayout> 

Hay dos oyentes más que usted necesita para poner en práctica: onItemClick de la lista y onClick para el botón. Ambos establecen el valor seleccionado y descartan el diálogo.

Para la lista, que quiere que se vea lo mismo que expandida Spinner, que puede hacer que la provisión del adaptador de lista con el estilo apropiado (Spinner) así:

ArrayAdapter<String> adapter = 
    new ArrayAdapter<String>(
     activity, 
     android.R.layout.simple_spinner_dropdown_item, 
     states 
    ); 

Más o menos, que debe ya sea

+0

Se ve bien. Estoy intentando implementar su solución, pero soy nuevo en el desarrollo de Android, y estoy un poco confundido acerca de dónde colocar los fragmentos. ¿Te importaría revisar un poco para explicar cómo implementarlo? –

2

por encargo :) puede utilizar las propiedades desplegables hori/desplazamiento vertical para colocar la lista actualmente, también intente con android: spinnerMode = "dialog" es más fresco.

Disposición

<LinearLayout 
     android:layout_marginBottom="20dp" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal"> 
     <AutoCompleteTextView 
      android:layout_weight="1" 
      android:id="@+id/edit_ip" 
      android:text="default value" 
      android:layout_width="0dp" 
      android:layout_height= "wrap_content"/> 
     <Spinner 
      android:layout_marginRight="20dp" 
      android:layout_width="30dp" 
      android:layout_height="50dp" 
      android:id="@+id/spinner_ip" 
      android:spinnerMode="dropdown" 
      android:entries="@array/myarray"/> 
</LinearLayout> 

Java

  //set auto complete 
     final AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.edit_ip); 
     ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, getResources().getStringArray(R.array.myarray)); 
     textView.setAdapter(adapter); 
     //set spinner 
     final Spinner spinner = (Spinner) findViewById(R.id.spinner_ip); 
     spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
      @Override 
      public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 
       textView.setText(spinner.getSelectedItem().toString()); 
       textView.dismissDropDown(); 
      } 
      @Override 
      public void onNothingSelected(AdapterView<?> parent) { 
       textView.setText(spinner.getSelectedItem().toString()); 
       textView.dismissDropDown(); 
      } 
     }); 

res/valores/cadena

<string-array name="myarray"> 
    <item>value1</item> 
    <item>value2</item> 
</string-array> 

¿Fue útil?

Cuestiones relacionadas