마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

다중 스피너 및 조건부 스피너 이벤트

0 추천
스피너를 계층적으로 이용하려고 합니다.

예를 들어 옷에 대한 분류를 스피너를 이용해 점차적으로 좁혀나간다고 가정합니다.

이때 가장 큰 분류를 성별이라고 하고 바로 다음 분류를 상의 혹은 하의라고 할때, 첫 번째 스피너의 값을 선택 했을 때, 추가로 다음 순서의 스피너가 나오도록 구현하려면 어떻게 해야 하나요?

여기서 추가적으로 두 번째 스피너로 아이템 중 하나를 선택 했을 때, 상의를 선택한 경우 상의에 대한 스피너를, 하의를 선택한 경우 하의에 대한 스피너만을 보여주기 위해서는 어떤 방식으로 구현해야 하나요?
블루는파랑 (160 포인트) 님이 2021년 2월 9일 질문

1개의 답변

+1 추천

개발자 문서의 스피너 페이지를 살펴보시면 예제까지 다 나옵니다.

https://developer.android.com/guide/topics/ui/controls/spinner

키 포인트는 Spinner.setAdapter에 ArrayAdapter를 통해 필요한 이이템을 세팅해 주시는 것과 

Spinner.setOnItemSelectedListener 를 통해서 선택된 아이템에 대한 로직을 구현하는 것입니다.

예를 들어 시,구, 동을 선택하는 스피너가 3개 있다고 치면,

 아래처럼 상위 Spinner의 ItemSelectedListener 이벤트를 통해 선택된 상위 스피너에 해당하는 하위 스피너의 아이템을 보여주시면 됩니다. 제 코드는 그냥 단순 참고용이니 참고만 하시고 카피하지는 마세요.

public class SpinnerActivity extends Activity implements OnItemSelectedListener {

   private Spinner siSpinner, guSpinner, dongSpinner;
   private ArrayAdapter siAdapter, guAdapter, dongAdapter;

    public void onCreate(Bundle savedInstance) {
          super.onCreate(savedInstance);
          
          
          dongAdapter = new ArrayAdapter(...)
          dongAdapter.setNotifyOnChange(true);
          dongSpinner = findViewById(R.id.dongSpinner);
          donSpinner.setAdapter(guAdapter);
          donSpinner.setOnItemSelectedListener(this);
 
          guApapter = new ArrayAdapter(...)
          guApapter.setNotifyOnChange(true);
          guSpinner = findViewById(R.id.guSpinner);
          guSpinner.setAdapter(guAdapter);
          guSipnner.setOnItemSelectedListener(this);


           privat final siList = getSiList();
           siAdapter = new ArrayAdapter(getContext, R.layout.item_layout_id, siList)
           siSpinner = findViewById(R.id.siSpinner);
           siSpinner.setAdapter(siAdapter);
           siSpinner.setOnItemSelectedListener(this); 
    }

    
    private String selectedSi, selectedGu;
    public void onItemSelected(AdapterView<?> parent, View view,
            int pos, long id) {

           String selectedItem = (String) parent.getSelectedItem();
           switch(prent.getId()) {
              case R.id.siSpinner -> 
                    selectedSi = selectedItem;
                    siSelected();
                    break;
              case R.id.guSpinner -> 
                    selectedGu = selectedItem;
                    guSelected();
                    break;
              case R.id.dongSpinner -> 
                   dongSelected(selectedItem);
                   break;
              default:
                  throw new RuntimeException("Unknown spinner selected");
           }
    }

    public void onNothingSelected(AdapterView<?> parent) {
        // Another interface callback
    }

   
   private void siSelected() {
         List<String> guList = getGuList(selectedSi);
         guAdapter.clear();
         guAdaper.addAll(guList);
   }

   private void guSelected() {
        List<String> dongList = getDongList(selectedSi, selectedGu);
         dongAdapter.clear();
         dongAdapter.addAll(dongList);
   }

   private void dongSelected(String dong) {
     
   }

   private List<String> getSiList() {
         //백그라운드에 시리스트를 구해서 리턴하세요.
    }

    private List<String> getGuList(si: String) {
       //백그라운드에 선택한 시의 구리스트를 구해서 리턴하세요.
    }

    private List<String> getDongList(si: String, gu: String) {
       //백그라운드에 선택한 시구의 동리스트를 구해서 리턴하세요.
    }
}

 

각 스피너의 아이템이 코드-값 이런 형태로 가지고 있어야 한다면 String대신에 클래스를 사용하시고 toString() 메소드를 오버라이드 해주시면 됩니다. 예를 들면

abstract class Clothes {
   protected String code;
   protected String name;
}

public class Tops extends Clothes {
     
}

public class Bottoms extends Clothes {
   
}


ArrayAdapter<Tops> topsAdapter = new ArrayAdapter(context, R.layout.layout_id, getTopsList());

 

Spinner 리스트의 디자인이 원하는 게 아닐경우는 커스텀 레이아웃을 이용해서 커스텀 ArrayAdapter를 사용하셔야 합니다.

spark (227,530 포인트) 님이 2021년 2월 10일 답변
spark님이 2021년 2월 10일 수정
...