web-dev-qa-db-fra.com

Comment afficher une liste déroulante sous Android?

Comment afficher une liste déroulante sous Android?

63
James

Dans Android, il s’appelle Spinner, vous pouvez consulter le didacticiel ici.

Bonjour Spinner

Et c'est une question très vague, vous devriez essayer d'être plus descriptif de votre problème. 

64
gruntled

Voici un exemple de liste déroulante personnalisée dans 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);
   }
}

J'espère que ça aide!!

10
Raneez Ahmed

Non testé, mais le plus proche semble être avec AutoCompleteTextView . Vous pouvez écrire un adaptateur qui ignore les fonctions de filtrage. Quelque chose comme:

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

... puis dans votre 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);

Le code n'est pas testé, il peut y avoir certaines fonctionnalités avec la méthode de filtrage que je n'ai pas envisagée, mais voilà les principes de base pour émuler un ComboBox avec un AutoCompleteTextView.

Edit Correction de l'implémentation de NullFilter. Nous avons besoin d’un accès sur les éléments, le constructeur de UnconditionalArrayAdapter doit donc prendre une référence à une liste (sorte de tampon). Vous pouvez également utiliser, par exemple, adapter = new UnconditionalArrayAdapter<String>(..., new ArrayList<String>);, puis utilisez adapter.add("Luxemburg"), vous n'avez donc pas besoin de gérer la liste des tampons.

6
vbence

Les questions sont parfaitement valables et claires puisque Spinner et ComboBox (lisez-le: Spinner où vous pouvez également fournir une valeur personnalisée) sont deux choses différentes.

Je cherchais la même chose moi-même et je n'étais pas satisfait des réponses données. Alors j'ai créé mon propre truc. Certains trouveront peut-être les indications suivantes utiles. Je ne fournis pas le code source complet, car j'utilise des appels hérités dans mon propre projet. Cela devrait être clair quand même.

Voici la capture d'écran de la dernière chose:

ComboBox on Android

La première chose à faire était de créer une vue qui ressemblerait à celle du disque qui n'a pas encore été développée. Dans la capture d'écran, en haut de l'écran (flou), vous pouvez voir la visionneuse et la vue personnalisée ci-dessous. Pour cela, j'ai utilisé LinearLayout (en fait, j'ai hérité de Linear Layout) avec style="?android:attr/spinnerStyle". LinearLayout contient TextView avec style="?android:attr/spinnerItemStyle". Un extrait de code XML complet serait:

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

Comme je l'ai mentionné précédemment, ComboBox hérite de LinearLayout. Il implémente également OnClickListener qui crée une boîte de dialogue avec une vue personnalisée gonflée à partir du fichier XML. Voici la vue gonflée:

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

Vous devez implémenter deux écouteurs supplémentaires: onItemClick pour la liste et onClick pour le bouton. Ces deux éléments définissent la valeur sélectionnée et ferment la boîte de dialogue.

Pour la liste, vous voulez qu'il ressemble à Spinner développé, vous pouvez le faire en fournissant à l'adaptateur de liste le style (Spinner) approprié, comme ceci:

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

Plus ou moins, ça devrait être ça.

5
Viktor Brešan

Personnalisé:) Vous pouvez utiliser les propriétés de décalage déroulant hori/vertical pour positionner la liste actuellement.

Disposition

  <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/valeurs/chaîne

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

Était-ce utile?

4
ShAkKiR

Pour une liste déroulante ( http://en.wikipedia.org/wiki/Combo_box ) qui permet la saisie de texte libre et comporte une liste déroulante, j’ai utilisé une AutoCompleteTextView comme suggéré par vbence.

J'ai utilisé la variable onClickListener pour afficher la liste déroulante lorsque l'utilisateur sélectionne le contrôle. 

Je crois que cela ressemble mieux à ce genre 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);
}
0
rve