Enable a currently disabled Spinner in Android

2019-02-28 10:33发布

问题:

I was fooling around with Android and my Java knowledge is limited at best (for instance, I'm perplexed by the fact that it allows inline classes!?).

My question is as follows:

I have a layout where there are three dropdown menus. I initialise all three of them inside onCreate().

The first one takes its values from a string-array. The second one, however, depends on the choice of the first one and the third one depends on the choice of the second one in turn!

I have a few string-arrays for the second Spinner but I was wondering what would be the correct way to implement a list of successively enabled Spinners. I'm tempted to just hack into it and make it work but I don't want to run the risk of it being malformed and unstable.

So for example's sakes, my case is as if I had the Google Spinner tutorial with an extra Spinner for the moons of each planet (and then maybe for craters on each of the moons).

In my resources, I have an arrays.xml such as:

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

In the onCreate method I initialise all three:

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

}

My listener class is

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

So there it is. My question is where and how to implement the listeners for the successive Spinners so that they're enabled once the first one is selected. My first guess is:

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

But obviously this is wrong since spinner2 is not encapsulated here.

Then, the successive spinners should pick a string-array for their adapters depending on what the choice of the Spinners before it are. I tried encapsulating the spinners in the activity class, in the constructor, but the application crashes before running.

Thank you very much in advance for your help.

回答1:

Use the view parameter of onItemSelected to decide which Spinner sent the onItemSelected event. From this doing the logic is simple.

Make spinner1 2 and 3 member of the class (activity)

private Spinner spinner1;

Then simply compare the view param against

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
}


回答2:

Try to use this :

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

    }

good luck !