¿Cómo puedo mostrar un cuadro combinado en Android? [cerrado]

80

¿Cómo puedo mostrar un cuadro combinado en Android?

James
fuente
1
Explique más claramente lo que desea. Y lo que ya has probado.
Traslado el
30
@fretje La pregunta es bastante específica. Si sabe qué es un ComboBox , no necesita explicación. Si no lo hace, puede
buscarlo en
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.
traste
18
@fretje Para Windows no sería lo suficientemente específico por razones obvias (puede hacerlo en C # o Delphi, etc.), pero en Android se está hablando de un marco de desarrollo único. Cuando se habla de Android , es tan específico como decir Visual Basic .Net .
vbence
prueba este ejemplo stackoverflow.com/a/17650125/2027232
Nicolas Tyler

Respuestas:

76

En Android se llama Spinner. Puedes echar un vistazo al tutorial aquí.

Hola, Spinner

Y esta es una pregunta muy vaga, debería tratar de ser más descriptivo de su problema.

gruñido
fuente
17
Le sugiero que considere esto en el contexto del desarrollo de Android. designerandroid.com/?p=8 . En el contexto de desarrollo de Android, se lo conoce como Spinner. Por favor, investigue la próxima vez.
gruñó
3
Sí, y al mirar el sitio que ha proporcionado, puede ver que sí mencionan un ComboBox en esa página, pero en la API solo hay una referencia a Spinner ( developer.android.com/resources/tutorials/views/… ) Aquí dicen claramente 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.
gruñó
3
Entiendo que la metáfora cambia un poco con las interfaces de usuario móviles. Hay nuevos widgets (controles) que pueden hacer un mejor uso del espacio limitado de la pantalla. Supongo que es por eso que los nuevos nombres usados ​​para algunos controles que son familiares forman la metáfora del escritorio. - Estoy de acuerdo en que el Spinner es similar a la lista desplegable. Sin embargo, la principal diferencia entre ListBox (lista desplegable) y ComboBox es que el cuadro combinado es básicamente un campo de entrada de texto ampliado con la posibilidad de elegir de la lista. Puede elegir un elemento de la lista o puede ingresar valores arbitrarios.
vbence
15
Deje de ser quisquilloso y admita que todos tuvieron problemas para encontrar un control que actúe como un cuadro combinado o un cuadro de lista la primera vez que escribieron una aplicación para Android ...
Torp
11
Todavía estoy buscando un cuadro combinado. He visto Spinners. Hilanderos usados. Pero, francamente, tengo un escenario en el que necesito establecer el texto en algo diferente a una opción determinada. También pueden escribir en él. Los hilanderos no son cuadros combinados, pero suelen ser una alternativa válida.
IAmGroot
11

Aquí hay un ejemplo de cuadro combinado personalizado 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 eso ayude!!

Raneez Ahmed
fuente
1
Gracias por su respuesta. Quiero usar este widget, pero quiero usar una matriz de String como fuente de datos, no como cursor. ¿Qué tengo que hacer?
Ali Behzadian Nejad
7

No probado, pero parece que lo más cerca que puede estar es con AutoCompleteTextView . Puede escribir un adaptador que ignore las funciones de filtro. Algo 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();
            }
        }
    }
}

... luego en tu 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 está probado, puede haber algunas características con el método de filtrado que no consideré, pero ahí lo tienen, los principios básicos para emular un ComboBox con un AutoCompleteTextView.

Edite la implementación de NullFilter fijo. Necesitamos acceder a los elementos, por lo que el constructor de las UnconditionalArrayAdapternecesidades debe tomar una referencia a una Lista (una especie de búfer). También puede usar eg adapter = new UnconditionalArrayAdapter<String>(..., new ArrayList<String>);y luego usar adapter.add("Luxemburg"), por lo que no necesita administrar la lista de búfer.

vbence
fuente
Este código no se acerca a la compilación. Las llamadas a getFilter () parecen intentos de un bucle infinito y publishResults devuelve un valor de un método void. La idea es buena en general, pero alguien debería arreglar este ejemplo.
Dhakim
6

Las preguntas son perfectamente válidas y claras ya que Spinner y ComboBox (léalo: Spinner donde también puede proporcionar un valor personalizado) son dos cosas diferentes.

Yo estaba buscando lo mismo y no estaba satisfecho con las respuestas dadas. Así que creé mi propia cosa. Quizás algunos encuentren útiles las siguientes sugerencias. No estoy proporcionando el código fuente completo porque estoy usando algunas llamadas heredadas en mi propio proyecto. De todos modos, debería quedar bastante claro.

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

ComboBox en Android

Lo primero fue crear una vista que se verá igual que la ruleta que aún no se ha expandido. En la captura de pantalla, en la parte superior de la pantalla (desenfocada), puede ver la ruleta y la vista personalizada a la derecha debajo. 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". El fragmento XML completo 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 mencioné 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 vista inflada:

<?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 necesita implementar: onItemClick para la lista y onClick para el botón. Ambos establecen el valor seleccionado y cierran el cuadro de diálogo.

Para la lista, desea que tenga el mismo aspecto que Spinner expandido, puede hacerlo proporcionando al adaptador de lista el estilo apropiado (Spinner) como este:

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

Más o menos, debería ser así.

Viktor Brešan
fuente
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. ¿Le importaría revisar un poco para explicar cómo implementarlo?
You'reAGitForNotUsingGit
4

Hecho a medida :) puede usar las propiedades de desplazamiento horizontal / vertical del menú desplegable para colocar la lista actualmente, también pruebe con android: spinnerMode = "dialog" es más genial.

Diseño

  <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?

ShAkKiR
fuente
como tu respuesta ¿Dónde hacer clic en AutoCompleteTextView y mostrar?
ZarNi Myo Sett gana
puede agregar eventos adicionales a AutoCompleteTextView o spinner como desee.
ShAkKiR
0

Para un cuadro combinado ( http://en.wikipedia.org/wiki/Combo_box ) que permite la entrada de texto libre y tiene un cuadro de lista desplegable, utilicé unAutoCompleteTextView como lo sugiere vbence.

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

Creo que esto se parece mucho a este tipo de cuadro combinado.

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);
}
rve
fuente