アクティビティに 2 つのスピナーがあり、2 番目のスピナーの選択セットは、ユーザーが最初のスピナーに対して選択したものに基づいています。上部のスピナーの OnItemSelectedListener で設定され、下部のスピナーの OnItemSelectedListener で参照されるアクティビティでプライベート クラス変数を使用して、正しい選択セットを取得します。
これはほとんど常に機能しますが、時々 (主にアプリが実行され、終了せずに、ユーザーがしばらくしてから再度開始した場合)、このローカル変数が設定されていないため、2 番目の Spinner の OnItemSelectedListener で null ポインター例外が発生します。これは、OnCreate の後、2 番目の Spinner の OnItemSelectedListener が最初の Spinner の前に呼び出されたことを示しています。
起動されるリスナーに特定の順序を強制する方法はありますか、またはこの 2 番目のスピナーの最初のスピナーへの依存を処理するためのより良い設計アプローチはありますか?
コード例: パッケージ com.crashtestdummylimited.navydecoder;
public class Test extends Activity {
// Variable that at times is still null
private ReferenceData referenceData;
private void setupSpinnerFromArray (int spinnerId, String stringArray[], OnItemSelectedListener listener) {
Spinner spinner = (Spinner) findViewById(spinnerId);
ArrayAdapter <CharSequence> adapter = new ArrayAdapter <CharSequence>(
this, android.R.layout.simple_spinner_item, stringArray);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(listener);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_screen);
// Setup Top (main) Spinner
Spinner spinner1 = (Spinner) findViewById(R.id.mainDecodeSpinner);
ArrayAdapter<CharSequence> adapter1 = ArrayAdapter.createFromResource(
this, R.array.level0_list_array, android.R.layout.simple_spinner_item);
adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner1.setAdapter(adapter1);
spinner1.setOnItemSelectedListener(new MainDecoderItemSelectedListener());
// Setup Bottom (dependent) Spinner
setupSpinnerFromArray(R.id.secondaryDecodeSpinner, R.array.level1_list_array, new SecondaryDecoderItemSelectedListener());
}
public class MainDecoderItemSelectedListener implements OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
String selectedString = parent.getItemAtPosition(pos).toString();
if (selectedString.equals("AAA")){
// Problem variable is set
referenceData = new RatingCodes();
setupSpinnerFromArray(R.id.secondaryDecodeSpinner, referenceData.getKeys(), new SecondaryDecoderItemSelectedListener());
}
else if (selectedString.equals("BBB")){
// Problem variable is set
referenceData = new IMSCodes();
setupSpinnerFromArray(R.id.secondaryDecodeSpinner, referenceData.getKeys(), new SecondaryDecoderItemSelectedListener());
}
// TODO: Improve what occurs if no match which should not occur
}
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing.
}
}
public class SecondaryDecoderItemSelectedListener implements OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
String key = parent.getItemAtPosition(pos).toString();
// **** referenceData being null at this point has caused crashed ****
String value = referenceData.getValue(key);
// ... Update text on activity screen ...
}
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing.
}
}
}