web-dev-qa-db-fra.com

Android Spinner avec différentes dispositions pour "état déroulant" et "état fermé"?

J'ai un Android vue Spinner dans ma mise en page. Je voudrais que ce spinner n'affiche qu'un seul élément de texte lorsqu'il est fermé, mais lorsque l'utilisateur clique dessus (c'est-à-dire qu'il ouvre la boîte de dialogue du spinner), je voudrais comme pour afficher des informations plus détaillées pour chaque élément, y compris une icône et une vue de texte de description supplémentaire. Comme il est maintenant le spinner affiche la même mise en page (icône, titre + description) dans les deux états.

Si j'attache un ArrayAdapter au spinner, alors j'obtiens l'accès à quelque chose appelé "setDropDownViewResource" mais ce n'est pas nécessairement ce dont j'ai besoin, car mes données de spinner sont récupérées à partir d'un curseur et non à partir d'un tableau d'aucune sorte (je l'ai, à partir de maintenant , créé mon propre adaptateur, étendant BaseAdapter).

Quelqu'un qui peut m'aider?

59
dbm

Vous devez créer une classe Adapter personnalisée pour le Spinner et écraser les deux méthodes getView() pour la vue fermée normale et - getDropDownView() pour la liste déroulante. Les deux méthodes doivent renvoyer un objet View pour un seul élément.

Jetez un oeil à ce tutoriel il pourrait vous aider à démarrer.

104
Flo

J'avais aussi des problèmes. Plutôt que de remplacer la classe, j'ai un moyen plus simple de le faire.

Mais vous devez d'abord comprendre la différence entre l'ID de ressource dans le constructeur de l'adaptateur et l'autre dans setDropDownViewResource(...). Par exemple,

SimpleAdapter adapter =
    new SimpleAdapter(ab.getThemedContext(), data, R.layout.actionbar_dropdown, new String[] { "EventID", "Icon" },
        new int[] { R.id.event_id, R.id.icon });

adapter.setDropDownViewResource(R.layout.actionbar_list_item);

R.layout.actionbar_dropdown est le style de spinner et R.layout.actionbar_list_item pour chaque élément de la liste.

J'ai utilisé SimpleAdapter ici, car si j'utilise ArrayAdapter, le xml ne peut être qu'un seul TextView.

R.layout.actionbar_list_item contient une TextView dont l'ID est event_id et une ImageView dont l'ID est icon.

R.layout.actionbar_dropdown est presque identique à actionbar_list_item, mais la visibilité d'ImageView de ce dernier est définie sur DISPARU .

De cette façon, chaque élément de la liste a une vue texte et une vue image, mais vous ne verrez qu'une vue texte sur le spinner.

14
AstraChen

En utilisant le code du tutoriel lié par Flo, j'ai créé le CustomSpinnerAdapter suivant afin d'afficher deux ensembles de chaînes différents, l'un lorsque les éléments sont affichés et l'autre lorsqu'il ne l'est pas. J'espère que ça aide quelqu'un.

public class CustomSpinnerAdapter extends ArrayAdapter<String> {

Context mContext;
int mTextViewResourceId;
String[] mObjects;
String[] mShortNameObjects;

public CustomSpinnerAdapter(Context context, int textViewResourceId,
                            String[] objects, String[] shortNameObjects) {
    super(context, textViewResourceId, objects);
    mContext = context;
    mTextViewResourceId = textViewResourceId;
    mObjects = objects;
    mShortNameObjects = shortNameObjects;
}

@Override
public View getDropDownView(int position, View convertView,
                            ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    TextView row = (TextView) inflater.inflate(mTextViewResourceId, parent, false);
    row.setText(mObjects[position]);

    return row;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    return getCustomView(position, convertView, parent);
}

public View getCustomView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    TextView row = (TextView) inflater.inflate(mTextViewResourceId, parent, false);
    row.setText(mShortNameObjects[position]);

    return row;
}
}

Et l'utilisation à l'intérieur d'un fragment:

CustomSpinnerAdapter mSpinnerAdapter = new CustomSpinnerAdapter(getActivity(), R.layout.spinner_item, getResources().getStringArray(R.array.action_filter), getResources().getStringArray(R.array.action_filter_short_names));

Enfin, la disposition de l'élément spinner:

spinner_item.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:textSize="18dip"
    Android:gravity="left"
    Android:textColor="@color/navdraw_list_item_background_default"
    Android:padding="5dip" />
10
AlvaroSantisteban

Définit uniquement la ressource de vue déroulante avec votre mise en page alternative:

ArrayAdapter<String> genderAdapter = new ArrayAdapter<>(this, R.layout.adapter_spinner_white, Constants.GENDER);
genderAdapter.setDropDownViewResource(R.layout.adapter_spinner_white_dropdown);
view.setAdapter(genderAdapter);

Pour moi, il ne s'agit que d'une mise en page avec un rembourrage supplémentaire, car mon fond de spinner est un dessin arrondi et nécessite cet espace supplémentaire.

8
Joao Polo

Appelez simplement la méthode setUpSpinner () après avoir obtenu la référence à spinner

// voici la méthode setUpSpinner

private void setupSpinner() {

    // Create adapter for spinner. The list options are from the String array it will use
    // the spinner will use the default layout
    ArrayAdapter spinnerAdapter = ArrayAdapter.createFromResource(this,
            R.array.array_dropdown_options, Android.R.layout.simple_spinner_item);

    // Specify dropdown layout style - simple list view with 1 item per line
    spinnerAdapter.setDropDownViewResource(Android.R.layout.simple_dropdown_item_1line);

    // Apply the adapter to the spinner
    spinner.setAdapter(spinnerAdapter);
   // spinner is referenced spinner by finViewById.

    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            String selection = (String) parent.getItemAtPosition(position);
            if (!TextUtils.isEmpty(selection)) {
                if (selection.equals(getString(R.string.item_a))) {
                    // your code for selected item whose id equals to id to R.string.item_a
                } else if (selection.equals(getString(R.string.item_b))) {
                    // your code
                } else {
                    // your code
                }
            }
        }

        // Because AdapterView is an abstract class, onNothingSelected must be defined
        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            // code for nothing selected in dropdown
        }
    });
}
1
Chetan Pawar