2010-12-13 14 views
6

Tengo un formulario de Android que necesita actualizarse en función de ciertas selecciones. La forma se compone actualmente de 2 Spinners (A y B). Spinner B no se crea hasta que se hace la selección de Spinner A. Después de realizar la selección, B se mostrará en la vista y su contenido se rellenará dinámicamente en función de la selección de A. Aquí está mi código:Android Spinner - Cómo seleccionar la lista predeterminada para ninguno

public class MyForm extends Activity 
{ 
    private final int SEL_ACTIVATE = 0; 
    private final int SEL_DEACTIVATE = 1; 

    private static final String[] actionList = {"Activate", "Deactivate" }; 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     table = (TableLayout) findViewById(R.id.table); 

     showListA(table); 
    } 

    public void showListA(View v) 
    {   
     rowAction = new TableRow(this); 

     Spinner spinner = new Spinner(this); 
     spinner.setPrompt("Select..."); 
     spinner.setOnItemSelectedListener(
      new OnItemSelectedListener() 
      { 
       public void onItemSelected(AdapterView<?> parent, View v, int position, long id) 
       { 
        switch (position) 
        { 
        case SEL_ACTIVATE: 
        case SEL_DEACTIVATE: 
         showListB(v); 
         break; 
        } 
       } 

       public void onNothingSelected(AdapterView<?> arg0) 
       { 
        // TODO Auto-generated method stub 
       } 
     }); 

     ArrayAdapter<String> adapter = new ArrayAdapter<String> (this, android.R.layout.simple_spinner_item, actionList); 
     adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line); 
     spinner.setAdapter(adapter); 

     rowAction.addView(tvAction); 
     rowAction.addView(spinner); 

     table.addView(rowAction, new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 
    } 

    ... 
} 

Este código funciona correctamente. Cuando se seleccionan "Activar" o "Desactivar" de la lista, se ejecuta showListB() que es muy similar a showListA() en la forma en que crea una nueva fila que contiene Etiqueta y Spinner.

El problema es que, de forma predeterminada, "Activate" se muestra en el Spinner que ejecuta showListB() y de inmediato, la segunda parte del formulario se crea en función de la opción "Activar". La única solución que se me ocurre es la de añadir un tercer campo a la Spinner así:

private static final String[] actionList = {"None", "Activate", "Deactivate" }; 

... 

switch (position) 
{ 
case SEL_NONE: 
    break; 
case SEL_ACTIVATE: 
case SEL_DEACTIVATE: 
    showListB(v); 
    break; 
} 

Esto funciona ... pero no quiero una tercera opción en la lista. Solo quiero que, de manera predeterminada, esté en blanco o muestre algún tipo de texto 'de aviso' que no sea una opción en la lista una vez que se presione. es posible?

Gracias

EDIT:

contenido xml:

<Spinner 
    android:id="@+id/spinnerAction" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"/> 

Respuesta

4

Mi-sizes.xml datos:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <string-array name="chunks"> 
     <item>2</item> 
     <item>4</item> 
     <item>8</item> 
     <item>16</item> 
     <item>32</item> 
    </string-array> 
</resources> 

En main.xml:

<Spinner android:id="@+id/spinnerSize" 
android:layout_marginLeft="50px" 
android:layout_width="fill_parent"     
android:drawSelectorOnTop="true" 
android:layout_marginTop="5dip" 
android:prompt="@string/SelectSize" 
android:layout_marginRight="30px" 
android:layout_height="35px" /> 

en código Java:

Spinner spinnerSize; 
ArrayAdapter adapter; 

... 

spinnerSize = (Spinner)findViewById(R.id.spinnerSize); 
adapter = ArrayAdapter.createFromResource(this, R.array.chunks, android.R.layout.simple_spinner_item); 
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
spinnerSize.setAdapter(adapter); 
spinnerSize.setOnItemSelectedListener(new MyOnItemSelectedListener()); 

... 

class MyOnItemSelectedListener implements OnItemSelectedListener { 

    public void onItemSelected(AdapterView<?> parent, 
     View view, int pos, long id) { 
     chunkSize = new Integer(parent.getItemAtPosition(pos).toString()).intValue(); 
    } 
    public void onNothingSelected(AdapterView<?> parent) { 
     // Dummy 
    } 
} 

Por lo tanto, aunque puedo ver 2 como mi primer elemento predeterminado, no ocurre nada a menos que el usuario realmente lo seleccione.

Espero que esto ayude!

+0

Proporcione los motivos cuando crea que la respuesta no es útil (-1), de esa forma todos pueden entender por qué esta respuesta no es buena y ¡mostrar la mejor manera de hacerlo! Gracias. – TheCottonSilk

+0

Para aclarar, esto funciona porque está configurando el 'OnItemSelectedListener' ** después de que ** haya configurado correctamente el' Adaptador'. –

+0

¿Qué es la variable chunkSize? – CACuzcatlan

-1

Prueba a poner esto en XML con el atributo de línea de comandos:

android:prompt="@string/prompt" 

Esto también va a llenar en la parte superior de el diálogo giratorio.

No lo he visto en la documentación. La solicitud no se puede aplicar directamente. El atributo prompt debe referenciarse desde otra fuente. Intente hacer referencia a un valor de cadena.

Documentación de Android:

android:prompt 

Since: API Level 
The prompt to display when the spinner's dialog is shown. 
Must be a reference to another resource, in the form "@[+][package:]type:name" or to a  theme attribute in the form "?[package:][type:]name". 
This corresponds to the global attribute resource symbol prompt. 
+0

creo que estoy haciendo esto en la fuente de Java a través 'spinner.setPrompt ("acciones disponibles");'. Pero intenté agregar su línea fuente en el XML y recibí el siguiente error: 'error: Error: tipos de cadena no permitidos (en 'prompt' con valor 'test').' Lo cual es extraño, porque la API para ' 'dice que el aviso debe ser un argumento válido ... – linsek

+0

Pasé por alto la referencia en la documentación. Petición debe ser referenciada. – Phobos

+0

Disculpe, no acabo de seguir su edición. "Intenta hacer referencia a un valor de cadena"? – linsek

1

The Spinner siempre tendrá una selección. Lo que puede hacer es hacer que el Spinner muestre algo así como "Seleccionar" o "Seleccionar una opción" ...

Para hacer esto usted puede hacer sus opciones de la lista para ser

actionList = {"Select", "Desactivate" } 

y

public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {    
     actionList[0] = "Activate"; 
     ... 
} 

o puede hacer algo más complicado como anulaciones de la Spinner Ver o poner un botón en vez sin nada en él y cuando se hace clic en crear su spinner.

2

Si lo desea, hay una bruja spinnerAdapter decorater añadir automáticamente un valor predeterminado:

 


    protected class SpinnerAdapterWithNoValue implements SpinnerAdapter { 

     private SpinnerAdapter _current; 
     private final static String defaultValue = "Choisir"; 

     public SpinnerAdapterWithNoValue(SpinnerAdapter base) { 
      _current = base; 
     } 

     @Override 
     public int getCount() { 
      return _current.getCount() + 1; 
     } 

     @Override 
     public Object getItem(int position) { 
      if (position == 0 || position == -1) { 
       return null; 
      } 
      return _current.getItem(position - 1); 
     } 

     @Override 
     public long getItemId(int position) { 
      if (position == 0 || position == -1) { 
       return -1; 
      } 
      return _current.getItemId(position - 1); 
     } 

     @Override 
     public int getItemViewType(int position) { 
      if (position == 0 || position == -1) { 
       return -1; 
      } 
      return _current.getItemViewType(position - 1); 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      if (position == 0 || position == -1) { 
       final TextView v = (TextView) ((LayoutInflater) getContext().getSystemService(
         Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.spinner_text, parent, false); 
       v.setText(defaultValue); 
       return v; 
      } 
      return _current.getView(position - 1, convertView, parent); 
     } 

     @Override 
     public int getViewTypeCount() { 
      return _current.getViewTypeCount(); 
     } 

     @Override 
     public boolean hasStableIds() { 
      return _current.hasStableIds(); 
     } 

     @Override 
     public boolean isEmpty() { 
      return _current.isEmpty(); 
     } 

     @Override 
     public void registerDataSetObserver(DataSetObserver observer) { 
      _current.registerDataSetObserver(observer); 
     } 

     @Override 
     public void unregisterDataSetObserver(DataSetObserver observer) { 
      // TODO Auto-generated method stub 
      _current.unregisterDataSetObserver(observer); 
     } 

     @Override 
     public View getDropDownView(int position, View convertView, ViewGroup parent) { 
      // TODO Auto-generated method stub 
      if (position == 0 || position == -1) { 
       CheckedTextView v = (CheckedTextView) ((LayoutInflater) getContext().getSystemService(
         Context.LAYOUT_INFLATER_SERVICE)).inflate(android.R.layout.simple_spinner_dropdown_item, parent, 
         false); 
       v.setText(defaultValue); 
       return v; 
      } 
      return _current.getDropDownView(position - 1, convertView, parent); 
     } 
    } 

 

entonces usted puede crear su propio spinner usar este decorater:

 


    public class SpinnerWithNoValue extends Spinner { 

     public SpinnerWithNoValue(Context context) { 
      super(context); 
     } 

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

     public SpinnerWithNoValue(Context context, AttributeSet attrs, int defStyle) { 
      super(context, attrs, defStyle); 
     } 

     @Override 
     public void setAdapter(SpinnerAdapter orig) { 
      final SpinnerAdapter adapter = new SpinnerAdapterWithNoValue(orig); 
      super.setAdapter(adapter); 

      try { 
       final Method m = AdapterView.class.getDeclaredMethod("setNextSelectedPositionInt", int.class); 
       m.setAccessible(true); 
       m.invoke(this, -1); 

       final Method n = AdapterView.class.getDeclaredMethod("setSelectedPositionInt", int.class); 
       n.setAccessible(true); 
       n.invoke(this, -1); 

      } catch (Exception e) { 
       throw new RuntimeException(e); 
      } 
     } 

     /* 
     * getSelectedItem renvoi null si la valeur par defaut est séléctionnée 
     * 
     * @see android.widget.AdapterView#getSelectedItem() 
     */ 
     @Override 
     public Object getSelectedItem() { 
      return super.getSelectedItem(); 
     } 
    } 

 

Sólo hay que cambiar la declaración spinner en su diseño xml:

 


com.myproject.SpinnerWithNoValue 

 

Si lo desea, usted puede cambiar el código para establecer el texto predeterminado en la etiqueta de su spinner.

-1

Soy solo un principiante en el desarrollo de aplicaciones de Android, y estaba enfrentando un problema similar; fue capaz de ordenar a cabo utilizando una Solución sencilla esto funcionó para mí, espero que no para usted también:

AdmissionActivity clase pública se extiende Actividad implementa OnItemSelectedListener {

int i; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    i=0; 
      ......... 

      } 

........ .....

public void onItemSelected(AdapterView<?> parent, View view, 
     int pos, long id){ 

    if(i!=0){ 
     //do wat you want; 
    } 
    else i=1; 
      } 
      //initially the activity will be loaded and nothing will happen (since 
       // i=0); and then appropriate action will be taken since i would hav been 

// cambiaron a otra sumtng

Cuestiones relacionadas