안드로이드에서 Spinner 는 꽤 많이 사용되는 widget 중에 하나 입니다. 이번에 위 그림과 같이 3가지 종류의 Spinner를 생성한 예제를 만들어 보았습니다. 첫번째 Spinner. Spinner 생성 (...

[안드로이드] Spinner 예제(동적생성, 글자색, 초기화, 반복선택)



안드로이드에서 Spinner 는 꽤 많이 사용되는 widget 중에 하나 입니다.
이번에 위 그림과 같이 3가지 종류의 Spinner를 생성한 예제를 만들어 보았습니다.

첫번째 Spinner.
Spinner 생성 (Basic)

두번째 Spinner.
Spinner 생성, Spinner 글자 속성 변경 (드롭다운뷰, 사용자뷰)

세번째 Spinner.
Spinner 동적생성, Spinner 글자 속성 변경 (드롭다운뷰, 사용자뷰), 반복선택 처리


내용중에 필요하신게 있다면 아래 소스코드를 다운로드하시고, 
아래 정리한 주요내용과 같이 확인하면 좋을거 같네요.
(예제를 직접 실행하셔서 확인하면 더 도움이 되지 않을까 싶습니다ㅎㅎ) 


Spinner 생성 (Basic)

  • ArrayAdapter 를 활용해서 Spinner를 생성
SpinnerEx1 = (Spinner) findViewById(R.id.spinner1);

SpinnerEx1.setAdapter(new ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, numberStringArray));

SpinnerEx1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                resultText1.setText(numberStringArray[position] + " 을 선택하셨습니다.");
                resultText4.setText("'onItemSelected' 호출 횟수 : " + (++count1));
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }

        });

Spinner 글자 속성 변경 (드롭다운뷰, 사용자뷰)

  • ArrayAdapter 를 상속받는 SpinnerAdapter 를 따로 정의하여 활용한다.
  • SpinnerAdapter 에서 getDropDownView, getView 오버라이딩을 통해 원하는 속성을 변경해준다.

SpinnerEx2 = (Spinner) findViewById(R.id.spinner2);

SpinnerEx2.setAdapter(new SpinnerAdapter(this, android.R.layout.simple_spinner_dropdown_item, numberStringArray));

SpinnerEx2.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                resultText2.setText(numberStringArray[position] + " 을 선택하셨습니다.");
                resultText5.setText("'onItemSelected' 호출 횟수 : " + (++count2));
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }

        });


    public class SpinnerAdapter extends ArrayAdapter<String> {

        Context context;
        String[] items = new String[]{};

        public SpinnerAdapter(final Context context, final int textViewResourceId, final String[] objects) {
            super(context, textViewResourceId, objects);
            this.items = objects;
            this.context = context;

        }

        @Override
        public View getDropDownView(int position, View convertView, ViewGroup parent) {

            if (convertView == null) {
                LayoutInflater inflater = LayoutInflater.from(context);
                convertView = inflater.inflate(
                        android.R.layout.simple_spinner_dropdown_item, parent, false);

            }

            TextView tv = (TextView) convertView.findViewById(android.R.id.text1);
            tv.setText(items[position]);
            tv.setBackgroundColor(Color.BLACK);
            tv.setTextColor(Color.WHITE);
            tv.setTextSize(15);
            return convertView;

        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            if (convertView == null) {
                LayoutInflater inflater = LayoutInflater.from(context);
                convertView = inflater.inflate(
                        android.R.layout.simple_spinner_item, parent, false);
            }

            TextView tv = (TextView) convertView.findViewById(android.R.id.text1);
            tv.setText(items[position]);
            tv.setTextColor(Color.RED);
            tv.setTextSize(15);
            return convertView;

        }

    }

Spinner 반복선택 (동적생성)

  • Spinner 의 특징 중 같은 Item 을 선택 했을 때 onItemSelected 를 따로 호출 하지 않는 특징을 가지고 있다. 반복 선택 했을 때 onItemSelected 를 호출하기 위해 사용한다.
  • Widget Spinner 를 상속받는 MySpinner 를 따로 정의하여 활용한다.
  • MySpinner 에서 setSelection 오버라이딩을 통해 반복 선택에도 onItemSelected 가 호출되도록 수정한다.
SpinnerEx3 = new MySpinner(this);

LinearLayout.LayoutParams lParams = new LinearLayout.LayoutParams(getUnitDipValue(120), LinearLayout.LayoutParams.WRAP_CONTENT);
lParams.gravity = Gravity.CENTER;
lParams.leftMargin = getUnitDipValue(10);
SpinnerEx3.setLayoutParams(lParams);
((LinearLayout) findViewById(R.id.layout)).addView(SpinnerEx3);

SpinnerEx3.setAdapter(new SpinnerAdapter(this, android.R.layout.simple_spinner_dropdown_item, numberStringArray));

SpinnerEx3.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

                resultText3.setText(numberStringArray[position] + " 을 선택하셨습니다.");
                resultText6.setText("'onItemSelected' 호출 횟수 : " + (++count3));
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }

        });



    public class MySpinner extends android.support.v7.widget.AppCompatSpinner {

        public MySpinner(Context context) {
            super(context);
        }

        public MySpinner(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        public MySpinner(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }

        @Override
        public void setSelection(int position, boolean animate) {

            boolean sameSelected = position == getSelectedItemPosition();
            super.setSelection(position, animate);

            if (sameSelected) {
                // Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
                getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());

            }

        }

        @Override

        public void setSelection(int position) {

            //boolean sameSelected = position == getSelectedItemPosition();
            super.setSelection(position);
            //if (sameSelected) {
            // Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
            getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());
            //}

        }

    }



끝으로..

기본적으로 Spinner 는 아이템을 선택했을 때 리스너 onItemSelected 를 호출하는데,
이 외에 (1) Spinner 가 생성 될 때 onItemSelected 가 호출되는 점(초기화 시점)과 
(2) 반복 선택에 있어서 onItemSelected 가 호출이 안되는 점이 
코딩에 있어서 주목해야될 부분이라고 생각합니다.
필요에 따라 이를 활용하거나 수정이 필요할거 같네요~

(1) 과 같이 생성될 때 호출되는게 싫다면 저 같은 경우는 스피너마다 리스너에 
Flag 를 통해서 생성 되는 시점에는 넘어가도록 처리를 하긴 했는데..... 
다른 좋은 방법이 있을까 찾고있어서 일단 소스코드에서 제외시키긴했습니다 ^^:;
혹시 좋은 방법을 알고계신 분이 있다면 공유 부탁드려요!



댓글 1개:

  1. 혹시, 3번 반복선택에 대한 예제 소스를 받을 수 있을까요.. 아무리 해도 되질 않네요 ㅠㅠ
    기존에 있던 Spinner에 반복선택이 가능하도록 하고 싶은데..

    답글삭제