Spinner 위젯
Spinner 는 MS Windows 의콤보박스 컨트롤과 유사한 위젯입니다. Spinner 위젯에는 한줄의 텍스트가 표시되고, 터치하면 팝업창이 나타나면서 ListView 와 유사한 목록이 나타납니다. 목록 중에서 하나를 선택하면 팝업창이 사라지고 선택된 항목의 텍스트로 바뀜니다.
사용방법은 ListView 와 거의 유사합니다.ArrayList 에 목록 데이터를 저장하고, ArrayAdapter 를 통해서 Spinner 위젯과 연결하면 됩니다. 자세한 사용법은 예제를 통해서설명 드리겠습니다.
(1) Spinner 와 ArrayList 연동하기
Spinner 위젯에 10개의 텍스트문자열을 표시하는 예제를 만들어 보겠습니다. 그리고 사용자가 항목을 선택하면 해당 항목의 내용을 TextView 위젯에 표시해 보겠습니다.
1) 새로운 소스 프로젝트를 생성하고 이름을 SpinnerEx라고 지정합니다. 소스 프로젝트를 생성하는 방법은 먼저번 시간에 했던것과 동일합니다.
2) 레이아웃 파일에(/res/layout/activity_main.xml)1개의 Spinner 위젯을 추가해 보겠습니다. 레이아웃파일에 아래와 같이 코드를 추가합니다.
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<Spinner
android:id="@+id/spinner1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<TextView
android:id="@+id/textMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world"/>
</RelativeLayout>
1개의 Spinner 위젯을추가했고 ID 를 spinner1 으로 지정했습니다. 그리고 자동으로 생성되는 TextView 위젯의 ID 를 textMessage 로 지정했습니다.
Graphical Layout 편집화면에서 확인해 보면 아래와 같습니다.
3) 이 상태로 에뮬레이터에서 실행해 보면 Spinner 에 아무것도 표시되지 않습니다. Spinner 에 항목을추가해 보겠습니다. Activity 소스파일(/src/~/MainActivity.java)을열고 아래와 같이 새로운 멤버변수 3개를 선언해 줍니다. 에러표시가나타나면 단축키 Ctrl+Shift+o 를 눌러주면 됩니다.
public class MainActivity extends Activity{
Spinner mSpinner1;
TextView mTextMessage;
ArrayList<String> mArGeneral;
mSpinner1 은 Spinner위젯의 핸들을 저장하는 변수입니다.
mTextMessage 는TextView 위젯의 핸들을 저장하는 변수입니다.
mArGeneral 은ListView 에 표시할 데이터를 저장하는 ArayList 배열 입니다.
ArrayList 배열에 10개의문자열을 저장하고 이것을 Spinner 와 연결하는 기능을 구현해 봅시다. MainActivity 클래스에 initSpinner() 라는 함수를생성하고 아래와 같이 코드를 입력합니다.
publicvoid initSpinner() {
String[]strTextList = {"Seoul", "Tokyo", "Newyork","Londeon",
"Baijing","Kongga", "Moscuba", "Singgapol",
"Pusan","Hongkong"};
mArGeneral= new ArrayList<String>();
for(inti=0 ; i < 10 ; i ++) {
mArGeneral.add(strTextList[i]);
}
ArrayAdapter<String>adapter;
adapter= new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item,mArGeneral);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinner1= (Spinner)findViewById(R.id.spinner1);
mSpinner1.setAdapter(adapter);
}
코드내용을 설명하자면, String 객체를 저장할 수 있는 ArrayList 배열 객체를 생성해서 mArGeneral 이라는변수명에 할당합니다.
for 루프를 사용해서 10개의문자열을 mArGeneral 에 저장합니다.
mArGeneral 를 Spinner와 연동하기 위해서 ArrayAdapter 객체를 생성해서 adapter 라는 이름의 변수에 할당합니다. ArrayAdapter 를생성할 때 레이아웃을 지정해야 하는데 여기서는 기본으로 제공되는 레이아웃 중에서 android.R.layout.simple_spinner_dropdown_item을 사용했습니다. 단일 항목만을 표시할 때 사용합니다. 참고로ArrayListView 예제에서와 같이 android.R.layout.simple_list_item_1을 사용해도 결과는 동일합니다.
그런 다음 Spinner 에 adapter를 전달합니다. 이렇게 하면 mArGeneral 에저장된 문자열 배열이 Spinner 에 전달되는 것입니다.
이제 Activity 가 생성될 때 위 함수를 호출해 주면 됩니다. onCreate() 함수 끝부분에 아래와 같이 새로운 코드를 추가합니다.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextMessage =(TextView)findViewById(R.id.textMessage);
initSpinner();
}
TextView 위젯의 핸들을 구해서 mTextMessage 라는 이름의 변수에 할당했습니다. 이 변수는잠시 후에 Spinner 에서 발생한 이벤트를 처리할 때 사용될 것입니다.
그런 다음 initSpinner() 함수를 호출해서 Spinner 위젯에 항목을 추가해 주었습니다.
이제 에뮬레이터에서 결과를 확인해 봅시다. Spinner 에 첫번째텍스트 항목이 표시된 것을 확인할 수 있습니다. Spinner 를 터치하면 팝업창이 나타나고 전체 목록이표시됩니다. 목록을 위아래로 드래그하면 이동합니다.
항목을 선택하면 팝업창이 사라지고 Spinner 에 선택된 항목의텍스트가 표시됩니다.
(2) Spinner 항목 선택 이벤트 처리 –이벤트 리스너 클래스 생성
사용자가 Spinner 의 항목을 선택하면 해당 항목의 텍스트를 TextView 위젯에 표시하는 기능을 구현해 봅시다.ArrayListView 예제와 동일하게 이벤트 리스너 클래스를 생성해서 처리하겠습니다.
1) Spinner 위젯의 클릭 이벤트를 받아서 처리하는 리스너 클래스를 생성합니다. MainActivity 클래스에아래와 같이 새로운 클래스를 생성합니다.
AdapterView.OnItemSelectedListenermItemSelectedListener =
newAdapterView.OnItemSelectedListener() {
publicvoid onItemSelected(AdapterView<?> parent, View view,
intposition, long id) {
StringstrItem = mArGeneral.get(position);
mTextMessage.setText(strItem);
}
publicvoid onNothingSelected(AdapterView<?> parent) {
mTextMessage.setText("NoItem Selected.");
}
};
소스코드를 설명하자면, AdapterView.OnItemSelectedListener는 팝업창 목록의 항목을 선택했을 때 발생하는 이벤트를 수신하는 리스너 클래스 입니다. 여기서는리스너 클래스를 재정의하면서 동시에 객체도 생성하였습니다. 리스너 객체의 이름은 mItemSelectedListener 로 지정하였습니다.
리스너 클래스 내부에 onItemSelected() 가 바로 항목선택 이벤트 함수입니다. 사용자가 ListView 위젯의항목을 터치하면 이 함수가 실행되는 것입니다.
4개의 파라미터가 전달되는데 가장 중요한 것은 3번째 position 입니다. 몇번째항목을 선택했는지를 알수 있습니다.
Spinner 에 저장된 항목 텍스트는 mArGeneral 이라는 이름의 ArrayList 객체에 저장되어있기 때문에 여기서 선택된 항목의 텍스트를 구할 수 있습니다.
ArrayList.Get() 함수에 인덱스 번호를 전달하면 텍스트를구할 수 있습니다.
마지막으로 ArrayList 배열에서 구한 텍스트를 TextView 위젯에 표시해주는 것입니다.
onNothingSelected() 함수는 사용자가 선택을 취소했을때 발생하는 이벤트를 처리합니다.
[Tip!]
ListView 위젯의 이벤트를 구하는 리스너는 AdapterView.OnItemClickedListener이고, 항목 선택 이벤트함수는 onItemClick() 입니다. Spinner 위젯의 이벤트를 구할때는 onItemSelected() 와onNothingSelected() 함수 2가지를 모두 정의해주어야 합니다. 그렇지 않으면 오류가 발생합니다.
2) 위에서 생성한 리스너 객체가 이벤트를 받으려면 Spinner위젯과 연결이 되어야 합니다. onCreate() 함수 끝부분에 아래와 같이 한줄을 추가해줍니다.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextMessage = (TextView)findViewById(R.id.textMessage);
initSpinner();
mSpinner1.setOnItemSelectedListener(mItemSelectedListener);
}
Spinner 위젯의 항목 선택 이벤트를 구하기 위해서 Spinner.setOnItemSelectedListener() 함수에 리스너 객체를 전달하였습니다. 이렇게 하면 사용자가 Spinner 위젯의 항목을 터치했을 때 mItemSelectedListener 객체의 onItemSelected() 함수가실행되는 것입니다.
3) 에뮬레이터에서 결과를 확인해 봅시다. 처음 실행될 때 자동으로 첫번째 항목의 텍스트가 TextView 에표시됩니다. Spinner 팝업창의 항목을 선택하면 화면 아래TextView 에 선택 항목의 내용이 표시됩니다.
(3) Spinner 항목 선택 이벤트 처리 –Activity 가 이벤트 리스너 클래스를 상속
이번에는 소스코드를 수정해서 Spinner 위젯의 이벤트 리스너를 생성하지 않고 Activity 가 이벤트를 직접 받도록 구현해 보겠습니다. 익숙해지면이 방식이 편리합니다.
1) MainActivity 클래스 시작 부분으로 가서 아래와 같이 AdapterView.OnItemSelectedListener 를 상속받는 코드를 추가합니다. 이렇게 하면 MainActivity 가 Spinner 위젯의 이벤트를 직접 수신할 수 있습니다.
public class MainActivity extends Activity
implementsAdapterView.OnItemSelectedListener {
2) 리스너가 MainActivity 로 변경되었기 때문에 위에서 onCreate() 함수 끝에 있는 코드를 아래와 같이수정합니다.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextMessage = (TextView)findViewById(R.id.textMessage);
initSpinner();
mSpinner1.setOnItemSelectedListener(this);
}
3) 마지막으로 이벤트 리스너 클래스를 삭제합니다. 아래와같이 주석처리해서AdapterView.OnItemSelectedListener 클래스를 삭제하고 내부 함수만 남겨둡니다.
//AdapterView.OnItemSelectedListenermItemSelectedListener =
// newAdapterView.OnItemSelectedListener() {
publicvoid onItemSelected(AdapterView<?> parent, View view,
intposition, long id) {
StringstrItem = mArGeneral.get(position);
mTextMessage.setText(strItem);
}
publicvoid onNothingSelected(AdapterView<?> parent) {
mTextMessage.setText("NoItem Selected.");
}
//};
4) 에뮬레이터에서 결과를 확인해 봅시다. 먼저 번과 동일하게 결과가 표시되면 성공입니다.