Android: Spinner с изменением ArrayAdapter — как определить?

Я хочу иметь три Spinner с содержимым, которое зависит друг от друга.

Например. Spinner1 отображает {item1, item2}, а Spinner2 либо {item3, item4}, либо {item5, item6} в зависимости от того, выбран ли item1 или item2 на Spinner1. То же самое я хочу для Spinner 3, который реагирует на изменения Spinner1 и/или Spinner2.

Для последнего я должен сначала определить, какой из возможных наборов значений отображается atm в Spinner2.

Мой вопрос похож на этот вопрос, но я не знаю, что делать после получения адаптера.

Это то, что у меня есть до сих пор:

ArrayAdapter adapter1 = (ArrayAdapter) spinner2.getAdapter();
if(items_spinner1[0].contentEquals(adapter1.getItem(0)))
{
    //...
}

Я получаю адаптер, запрашиваю первое значение и сравниваю его с первым строковым значением моего массива, чтобы идентифицировать его. Мне это совсем не кажется элегантным. Есть ли более простое решение?


person jellyfish    schedule 17.03.2011    source источник


Ответы (1)


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

adapter1.getItem(0) возвращает первый элемент в списке, а не текущий выбранный элемент. Чтобы получить текущий выбранный элемент, используйте метод счетчика (не адаптера) getSelectedItem().

Вы можете, например, поместить что-то подобное в свой первый Spinner onItemSelectedListener (отредактированный на основе вашего комментария ниже):

public void onItemSelected (AdapterView<?> parent, View view, int position, long id) {
    Object selectedItem = parent.getSelectedItem();

    // Do this if the first Spinner has a set of options that are
    // known in advance.
    if (/*selectedItem is something*/) {
        // Set up the second Spinner in some way
    } else if (/*selectedItem is something else*/) {
        // Set up the second Spinner in another way
    }

    // OR, if you need to do something more complex
    // that would cause too much clutter here, do this.
    fillSecondSpinner(selectedItem);
}

Затем поместите что-то подобное в onItemSelectedListener второго счетчика Spinner. Получите выбранные элементы из первого и второго счетчиков, используя getSelectedItem() (или позиции элемента, используя getSelectedItemId() для первого и параметр position для второго). Используйте выбранные элементы для настройки третьего.

Изменить: OnItemSelectedListener для второго счетчика будет выглядеть примерно так.

// This must be defined in the enclosing scope.
final Spinner firstSpinner;  // Must be final to be accessible from inner class.
Spinner secondSpinner;
// ...
secondSpinner.setOnItemSelectedListener(new OnItemSelectedListener {
    public void onItemSelected (AdapterView<?> parent, View view, int position, long id) {
        // Again, usually the selected items should be of
        // a more specific type than Object.
        Object firstSelection = firstSpinner.getSelectedItem();
        Object secondSelection = parent.getSelectedItem();

        fillThirdSpinner(firstSelection, secondSelection);
    }

public void onNothingSelected (AdapterView<?> parent) { }
});
person erichamion    schedule 17.03.2011
comment
Вы говорите, что содержимое более поздних счетчиков зависит от выбора в более ранних, но опубликованный вами код зависит только от содержимого счетчика. - Извините, тогда я недостаточно ясно выразился... содержимое Spinner2 зависит только от выбора Spinner1, а содержимое Spinner3 зависит от выбора И содержимого Spinner2. (Предполагается, что пользователь будет перемещаться по древовидной структуре.) С частью выбора я уже разобрался, поэтому теперь ищу способ определить содержимое второго счетчика. - person jellyfish; 18.03.2011
comment
Если нет простого способа, я мог бы просто сохранить во флаге, какой контент я добавил в Spinner2 после выбора в Spinner1. Но поскольку я не знаю, сколько возможного содержимого может иметь Spinner2, я бы предпочел найти другой способ. - person jellyfish; 18.03.2011
comment
@jellyfish: Насколько я знаю, если вы не создадите свой собственный адаптер, который напрямую раскрывает свою модель данных, getItem(int) - единственный способ увидеть, что такое содержимое. Однако, если содержимое второго Spinner зависит от выбора в первом, вы можете легко увидеть, что представляет собой первый выбор. Вы также можете сохранить ссылку на массив (или список), который вы передаете второму адаптеру, и убедиться, что массив всегда обновляется, чтобы быть правильным. - person erichamion; 18.03.2011
comment
Спасибо, это поможет! :) - person jellyfish; 18.03.2011