2010-12-13 20 views
6

Ho un modulo Android che deve aggiornarsi in base a determinate selezioni. Il modulo è attualmente composto da 2 Spinners (A e B). Spinner B non creato fino a quando la selezione di Spinner A non viene effettuata. Dopo aver effettuato la selezione, B verrà visualizzato nella vista e il contenuto sarà riempito dinamicamente in base alla selezione di A. Ecco il mio codice:Spinner Android - Come selezionare la lista predefinita su nessuna

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

    ... 
} 

Questo codice funziona correttamente. Quando si seleziona "Attiva" o "Disattiva" dall'elenco, viene eseguito showListB() che è molto simile a showListA() in come crea una nuova riga che contiene Etichetta e Spinner.

Il problema è che, per impostazione predefinita, "Attiva" è visualizzato nello Spinner che esegue showListB() e subito dopo il blocco, la seconda parte del modulo viene creata in base all'opzione "Attiva". L'unica soluzione che posso venire in mente è di aggiungere un terzo campo per la Spinner in questo modo:

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

... 

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

Questo funziona ... ma non voglio una terza opzione nella lista. Voglio solo che, di default, sia vuoto o mostri una sorta di testo 'prompt' che non è un'opzione nella lista una volta che viene premuto. È possibile?

Grazie

EDIT:

contenuto XML:

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

risposta

4

miei dati-sizes.xml:

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

In 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" /> 

nel codice 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 
    } 
} 

Quindi, anche se posso vedere 2 come il mio primo oggetto predefinito, non succede nulla a meno che l'utente non lo selezioni effettivamente.

Spero che questo aiuti!

+0

Si prega di fornire dei motivi quando si ritiene che la risposta non sia utile (-1), in questo modo tutti possono capire perché questa risposta non è buona e mostra il modo migliore per farlo! Grazie. – TheCottonSilk

+0

Per chiarire, questo funziona perché stai impostando 'OnItemSelectedListener' ** dopo ** hai impostato' Adapter 'corretto? –

+0

Qual è la variabile chunkSize? – CACuzcatlan

-1

Provare a impostare questo in XML con l'attributo di richiesta:

android:prompt="@string/prompt" 

Questo sarà anche compilare nella parte superiore del la finestra di dialogo dello spinner.

Ho trascurato questo nella documentazione. Il prompt non può essere applicato direttamente. L'attributo prompt deve essere referenziato da un'altra fonte. Prova a fare riferimento a un valore di stringa.

Documentazione da 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

credo che sto facendo questo nel codice Java tramite 'spinner.setPrompt ("azioni disponibili");'. Ma ho appena tentato di aggiungere la tua linea sorgente nell'XML e ho ricevuto il seguente errore: 'errore: Errore: tipi di stringhe non permessi (a 'prompt' con valore 'test').' Che è dispari, perché l'API per ' 'dice prompt dovrebbe essere un argomento valido ... – linsek

+0

Ho trascurato il riferimento nella documentazione. Il prompt deve essere referenziato. – Phobos

+0

Mi dispiace, non seguo abbastanza la tua modifica. "Prova a fare riferimento a un valore stringa"? – linsek

1

Lo Spinner avrà sempre una selezione. Quello che puoi fare è far visualizzare a Spinner qualcosa come "Seleziona" o "Seleziona un'opzione" ...

Per fare questo si può fare le opzioni elenco da

actionList = {"Select", "Desactivate" } 

e

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

o si può fare qualcosa di più complicato, come le sostituzioni del Spinner Visualizza o mettere al posto di un pulsante con niente su di esso e quando viene cliccato crei il tuo spinner.

2

Se si vuole, c'è una spinnerAdapter strega decorater aggiungere automaticamente un valore predefinito:

 


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

 

Quindi è possibile creare il proprio filatore di utilizzare questo 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(); 
     } 
    } 

 

Basta cambiare la dichiarazione spinner nel tuo layout xml:

 


com.myproject.SpinnerWithNoValue 

 

Se vuoi, tu puoi cambiare il codice per impostare il testo predefinito nel tag della tua selezione.

-1

Sono solo un principiante nello sviluppo di app Android e ho riscontrato un problema simile; è stato in grado di risolvere la questione con un semplice soluzione- questo ha funzionato per me, spero lo fa anche per voi:

public class AdmissionActivity estende Attività 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 

// cambiato in sumtng altro