Android Spinner с разными макетами для «выпадающего состояния» и «закрытого состояния»? - PullRequest
58 голосов
/ 10 января 2011

В моем макете есть представление Android Spinner. Я хотел бы, чтобы этот счетчик отображал только один текстовый элемент в закрытом состоянии, но когда пользователь щелкает по нему (т.е. открывает диалоговое окно счетчика), я хотел бы показать более подробную информацию для каждого элемента, включая значок и дополнительное текстовое представление описания. , Как и сейчас, счетчик показывает одинаковое расположение (значок, заголовок + описание) в обоих состояниях.

Если я присоединяю ArrayAdapter к спиннеру, то я получаю доступ к чему-то, называемому "setDropDownViewResource", но это не обязательно то, что мне нужно, так как данные моего спиннера выбираются из курсора, а не из какого-либо массива (у меня есть, на данный момент создал свой собственный адаптер, расширяющий BaseAdapter).

Кто-нибудь, кто может мне помочь?

Ответы [ 5 ]

103 голосов
/ 10 января 2011

Вы должны создать пользовательский класс Adapter для Spinner и перезаписать два метода getView() для нормального закрытого просмотра и getDropDownView() для выпадающего списка.Оба метода должны возвращать объект View для одного элемента.

Посмотрите это руководство , оно может помочь вам начать работу.

14 голосов
/ 30 июня 2013

У меня тоже были проблемы. Вместо того, чтобы переопределять класс, у меня есть более простой способ сделать это.

Но сначала вам нужно понять разницу между идентификатором ресурса в конструкторе адаптера и другим в setDropDownViewResource(...). Например,

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 - это стиль для счетчик и R.layout.actionbar_list_item для каждого элемента списка.

Я использовал здесь SimpleAdapter, поскольку, если я использую ArrayAdapter, xml может быть только одним TextView.

R.layout.actionbar_list_item содержит TextView с идентификатором event_id и ImageView с идентификатором icon.

R.layout.actionbar_dropdown почти такой же, как actionbar_list_item, но видимость последнего для ImageView установлена ​​на GONE .

Таким образом, каждый элемент списка имеет текстовое представление и изображение, но вы увидите только текстовое представление на счетчике.

10 голосов
/ 18 июня 2014

Используя код руководства, связанного с Flo, я создал следующий CustomSpinnerAdapter, чтобы показать два разных набора строк: один, когда элементы отображаются, а другой, когда нет.Надеюсь, это кому-нибудь поможет.

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

И использование внутри фрагмента :

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

Наконец, макет для элемента счетчика:

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" />
8 голосов
/ 27 февраля 2016

Устанавливает только ресурс раскрывающегося списка с вашим альтернативным макетом:

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

Для меня это только макет с дополнительным отступом слева, потому что мой фон счетчика закруглен и требует этого дополнительного пространства.

1 голос
/ 14 июля 2018

Просто вызовите метод setUpSpinner () после получения ссылки на счетчик

// здесь есть метод 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
        }
    });
}

...