Включить отключенный в настоящее время Spinner в Android

Я дурачился с Android, и мои знания Java в лучшем случае ограничены (например, меня озадачивает тот факт, что он допускает встроенные классы!?).

Мой вопрос заключается в следующем:

У меня есть макет, в котором есть три выпадающих меню. Я инициализирую все три из них внутри onCreate().

Первый берет свои значения из массива строк. Однако второе зависит от выбора первого, а третье, в свою очередь, зависит от выбора второго!

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

Так, например, мой случай выглядит так, как если бы у меня было руководство по Google Spinner. с дополнительным Spinner для лун каждой планеты (а затем, возможно, для кратеров на каждой из лун).

В моих ресурсах у меня есть arrays.xml, например:

<resources>

<string-array name="planets">
    <item>Mercury</item>
    <item>Venus</item>
    <item>Earth</item>
    <item>Mars</item>
    <item>Jupiter</item>
    <item>Saturn</item>
    <item>Uranus</item>
    <item>Neptune</item>
</string-array>
<string-array name="earth">
    <item>The Moon</item>
</string-array>
<string-array name="mars">
    <item>Deimos</item>
    <item>Phobos</item>
</string-array>
<string-array name="jupiter">
    <item>Metis</item>
    <item>Adrasthea</item>
    <item>Amalthea</item>
    <item>Thebe</item>
    <item>Io</item>
    <item>Europa</item>
    <item>Ganymede</item>
    <item>Callisto</item>
 [...] etc. etc. 
</resources>

В методе onCreate я инициализирую все три:

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  Spinner spinner1 = (Spinner) findViewById(R.id.planetSpinner);
  Spinner spinner2 = (Spinner) findViewById(R.id.moonSpinner);
  Spinner spinner3 = (Spinner) findViewById(R.id.craterSpinner);
  spinner2.setEnabled(false);
  spinner3.setEnabled(false);
  ArrayAdapter adapter1 = ArrayAdapter.createFromResource(
        this, R.array.planets, android.R.layout.simple_spinner_item);
  adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
  spinner1.setAdapter(adapter1);
  spinner1.setOnItemSelectedListener(new MyOnPlanetSelectedListener());

}

Мой класс слушателя

public class MyOnPlanetSelectedListener implements OnItemSelectedListener {

public void onItemSelected(AdapterView<?> parent,
    View view, int pos, long id) {
  Toast.makeText(parent.getContext()), "The planet is " +
      parent.getItemAtPosition(pos).toString(), Toast.LENGTH_LONG).show();
 }

public void onNothingSelected(AdapterView parent) {
  // Do nothing.
  }
}

Вот оно. Мой вопрос заключается в том, где и как реализовать прослушиватели для последовательных Spinners, чтобы они включались после выбора первого. Моя первая догадка:

    public class MyOnPlanetSelectedListener implements OnItemSelectedListener {

public void onItemSelected(AdapterView<?> parent,
    View view, int pos, long id) {
  Toast.makeText(parent.getContext()), "The planet is " +
      parent.getItemAtPosition(pos).toString(), Toast.LENGTH_LONG).show();

  spinner2.setEnabled(true);

 }

public void onNothingSelected(AdapterView parent) {
  // Do nothing.
  }
}

Но, очевидно, это неправильно, так как spinner2 здесь не инкапсулирован.

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

Заранее большое спасибо за вашу помощь.


person adricv    schedule 04.08.2010    source источник


Ответы (2)


Используйте параметр view для onItemSelected, чтобы решить, какой Spinner отправил событие onItemSelected. Отсюда логика проста.

Сделать spinner1 2 и 3 членом класса (деятельность)

private Spinner spinner1;

Затем просто сравните параметр view с

if (view==this.spinner1) {
   // event came from spinner 1
   // create a new adapter, assign the new adapter to spinner 2
} else if (view==this.spinner2) {
   // event came from spinner 2
}
person Pentium10    schedule 04.08.2010
comment
Хей, Спасибо! Просто для пояснения, вы хотите реализовать один единственный слушатель для всех трех Spinner, проверяя только внутри слушателя, чтобы увидеть, из какого Spinner он пришел? - person adricv; 04.08.2010
comment
Мне ужасно жаль, не могли бы вы объяснить чуть подробнее, как бы вы это реализовали? Я совершенно потерян. Еще раз спасибо! - person adricv; 04.08.2010
comment
Да, вам нужен один слушатель для всех трех счетчиков. - person Pentium10; 04.08.2010
comment
Спасибо, я был бы просто признателен за дополнительный указатель того, как именно использовать параметр представления, чтобы получить, какой Spinner отправил событие, если вы не возражаете! Ваше здоровье. - person adricv; 04.08.2010
comment
Ага, теперь я понял, что вы имеете в виду, большое спасибо, я попробую! - person adricv; 04.08.2010
comment
хм, хотя просто быстрый концептуальный вопрос: конечно, если я создам счетчики 1, 2 и 3 в классе Activity, они все равно не будут инкапсулированы в классе OnMyItemSelectedListener? так что "это" ни к чему не приведет? До сих пор не вернуться домой, чтобы попробовать. - person adricv; 04.08.2010
comment
если это частный класс, он разрешит доступ к полям родительского класса. В конце концов попробуйте более длинную форму имени MyActivityName.this.spinner1 - person Pentium10; 04.08.2010
comment
Блестяще, спасибо! Вы также прояснили вопрос об инкапсуляции, который мучил меня в затылке. - person adricv; 04.08.2010

Попробуйте использовать это:

    switch(parent.getId())
    {
    case R.id.spinner1:
        Log.d(TAG,"spinner1");
        break;
    case R.id.spinner2:
        Log.d(TAG,"spinner2");
         break;

    }

удачи !

person sami boussacsou    schedule 04.10.2010