Вы можете изменить его так. Это все еще долго, поскольку часть этого может быть обобщена, но это более читабельно.
BookActivity
public class BookActivity extends AppCompatActivity {
Spinner sp1, sp2, sp3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book);
sp1 = (Spinner) findViewById(R.id.sp1);
sp2 = (Spinner) findViewById(R.id.sp2);
sp3 = (Spinner) findViewById(R.id.sp3);
initSpinner1();
}
private void initSpinner1() {
final List<String> list = new ArrayList<>();
list.add("Category1");
list.add("Category2");
list.add("Category3");
initSpinner(sp1, list, new SpinnerListener.Callback() {
@Override
public void onResult(String itemName) {
initSpinner2(itemName);
}
});
}
private void initSpinner2(String selectedCategory) {
final List<String> list = new ArrayList<>();
switch (selectedCategory) {
case "Category1":
list.add("Category1-1");
list.add("Category1-2");
list.add("Category1-3");
break;
case "Category2":
list.add("Category2-1");
list.add("Category2-2");
list.add("Category2-3");
break;
case "Category3":
list.add("Category3-1");
list.add("Category3-2");
list.add("Category3-3");
break;
default:
break;
}
initSpinner(sp2, list, new SpinnerListener.Callback() {
@Override
public void onResult(String itemName) {
initSpinner3(itemName);
}
});
}
public void initSpinner3(String selectedCategory) {
final List<String> list = new ArrayList<>();
switch (selectedCategory) {
case "Category1-1":
list.add("Category1-1-1");
list.add("Category1-1-2");
list.add("Category1-1-3");
break;
case "Category1-2":
list.add("Category1-2-1");
list.add("Category1-2-2");
list.add("Category1-2-3");
break;
case "Category1-3":
list.add("Category1-3-1");
list.add("Category1-3-2");
list.add("Category1-3-3");
break;
default:
break;
}
initSpinner(sp3, list, new SpinnerListener.Callback() {
@Override
public void onResult(String itemName) {
// TODO
}
});
}
private void initSpinner(Spinner spinner, List<String> list, SpinnerListener.Callback callback) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
final AdapterView.OnItemSelectedListener listener = new SpinnerListener(this, callback);
spinner.setOnItemSelectedListener(listener);
}
}
Реализация OnItemSelectedListener
public class SpinnerListener implements AdapterView.OnItemSelectedListener {
private final Context mContext;
private final Callback mCallback;
public SpinnerListener(Context context, Callback callback) {
mContext = context;
mCallback = callback;
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
final String itemName = parent.getItemAtPosition(position).toString();
Toast.makeText(mContext, "YOUR SELECTION IS : " + itemName, Toast.LENGTH_SHORT).show();
mCallback.onResult(itemName);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing
}
public interface Callback {
void onResult(String itemName);
}
}
Код можно немного сократить, если вы используете лямбда-функцию (Java 8). Например:
initSpinner(sp2, list, new SpinnerListener.Callback() {
@Override
public void onResult(String itemName) {
initSpinner3(itemName);
}
});
можно записать:
initSpinner(sp2, list, itemName -> initSpinner3(itemName));
или даже короче:
initSpinner(sp2, list, this::initSpinner3);
EDIT
Или вы можете сделать что-то подобное, используя массивы String вместо списков. Вы можете экспортировать методы для инициализации массива в отдельный файл, чтобы облегчить код в Activity:
public class BookActivity extends AppCompatActivity {
Spinner sp1, sp2, sp3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book);
sp1 = (Spinner) findViewById(R.id.sp1);
sp2 = (Spinner) findViewById(R.id.sp2);
sp3 = (Spinner) findViewById(R.id.sp3);
initSpinner1();
}
private void initSpinner1() {
final String[] list = SpinnerArrayInitializer.getSpinner1Array();
initSpinner(sp1, list, itemName -> initSpinner2(itemName));
}
private void initSpinner2(String selectedCategory) {
final String[] list = SpinnerArrayInitializer.getSpinner2Array(selectedCategory);
initSpinner(sp2, list, itemName -> initSpinner3(itemName));
}
public void initSpinner3(String selectedCategory) {
final String[] list = SpinnerArrayInitializer.getSpinner3Array(selectedCategory);
initSpinner(sp3, list, itemName -> {
// TODO
});
}
private void initSpinner(Spinner spinner, String[] list, SpinnerListener.Callback
callback) {
final ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
final AdapterView.OnItemSelectedListener listener = new SpinnerListener(this, callback);
spinner.setOnItemSelectedListener(listener);
}
}
И для инициализации массивов:
public interface SpinnerArrayInitializer {
static String[] getSpinner1Array() {
return new String[]{"Category1", "Category2", "Category3"};
}
static String[] getSpinner2Array(String selectedCategory) {
switch (selectedCategory) {
case "Category1":
return new String[]{"Category1-1", "Category1-2", "Category1-3"};
case "Category2":
return new String[]{"Category2-1", "Category2-2", "Category2-3"};
case "Category3":
return new String[]{"Category3-1", "Category3-2", "Category3-3"};
default:
return new String[0];
}
}
static String[] getSpinner3Array(String selectedCategory) {
switch (selectedCategory) {
case "Category1-1":
return new String[]{"Category1-1-1", "Category1-1-2", "Category1-1-3"};
case "Category1-2":
return new String[]{"Category1-2-1", "Category1-2-2", "Category1-2-3"};
case "Category1-3":
return new String[]{"Category1-3-1", "Category1-3-2", "Category1-3-3"};
default:
return new String[0];
}
}
}