이번에는 ListView, Spinner, Grid와 같이
사용자가 키보드나 가상키보드 타이핑으로 정보를 입력 하지 않고,
미리 정의된 data set 중 원하는 데이터 고를 수 있게 도와주는 selection 위젯에 대해 알아본다.
1. Adapter
먼저 selection위젯에 data를 공급하고 모양도 결정하는 Adapter객체에 대해 알아보자
Adapter의 역할
안드로이드에서 adapter는 다음과 같은 역할을 한다.
- selection 위젯(List, combo, spinner등)에 일관된 interface로 data 공급.
- adapter가 공급한 data가 어떤 형식의view를 통해 selection 위젯에 표현 될지를 결정.
Adapter 종류
안드로이드에서 제공하는 adapter는 여러 종류가 있다. 다음은 자주 쓰이는 adapter이다.
- CursorAdapter: Cursor(DB Query 결과에 랜덤하게 읽고 쓸 수 있게 해주는 interface)로부터 데이터를 selection 위젯에 공급하는 adapter. Content Provider (뒷 chapter에 자세히 다룸)가 제공하는 data를 selection위젯에 연결할 때 도 사용함.
- SimpleAdapter: data를 XML Layout 파일에 지정된 View형태로 표하는데 사용 함.
- ActivityAdapter, ActivityIconAdapter: 특정 Intent 발생 시 실행될 activity의 이름이나 아이콘 목록을 위한 adapter.
- ArrayAdapter: array나 java.util.List에 저장된 data를 위한 adapter.
ArrayAdapter사용법
Adapter중 가장 사용이 간편한 ArrayAdapter는 array 또는 java.util.List에 저장된 data를 selection 위젯에 공급한다. 다음은 ArrayAdapter의 상속 구조이다.
다음은 사용법이다.
String items[] = { "How", "to", "use", "ArrayAdapter?" };
ArrayAdapter <String> aa = new ArrayAdapter <String> (this,
android.R.layout.simple_list_item_1,
items);
ListView 인스턴스.setAdapter(aa);
첫 번째로, ArrayAdapter객체를 생성하여야 한다. 위의 생성자 호출에 사용된 인자들은 다음과 같다.
- this – 사용할 Context (일반적으로 아답터를 포함하는activity의 instance)
- android.R.layout.simple_list_item_1 – Selection 위젯의 각 아이템을 채울 view의 resource ID. TextView가 포함된 layout파일을 전달하며, 여기에 어떤 형식의 TextView 리소스를 지정하느냐에 따라 selection 위젯을 구성하는 각 아이템의 text 형태(글씨의 크기, 색깔, 배경, 스타일 등)가 바뀜.
- items – Selection 위젯에 나열될 array나 java.util.List형식의 data. ArrayAdapter는 공급된 data의 모든 요소를 toString() 메소드로 String화 하고, 위의 리소스ID 파라미터에 정의된 형태의 view 형태로 표현한다. 이 예제의 경우 android.R.layout.simple_list_item_1은 기본 TextView임으로 배열의 각 요소는 일반적인 text로 표현됨.
두 번째로, ListView의 setAdapter 메소드를 이용하여 ListView와 adapter를 연결 한다.
위ArrayAdapter 생성자의 2번째 인자, android.R.layout.simple_list_item_1은 안드로이드 Library가 기본으로 제공하는 selection 위젯 를 위한 많은 아이템 layout파일 중 하나이며, 다음과 같이 기본 TextView의 형태로 ListView 아이템을 표현한다.
하지만, ListView에 표시되는 text의 모양을 커스터마이징 하고 싶다면, \res\layout\ 밑에 원하는 스타일의 element가 선언 되어 있는 XML layout file을 추가하고
ArrayAdapter 생성시 2번째 인자로 새로운 layout 리소스 파일(R.layout.새로운layout파일이름)을 지정하면 된다. 다음은 예에서는 text에 50px크키, 빨간색, bold|italic을 적용한 예이다.
listview_item_layout_01.xml (파일이름에 대문자 사용 못함)
1 |
<? xml version = "1.0" encoding = "utf-8" ?> |
4 |
android:layout_width = "fill_parent" |
5 |
android:layout_height = "wrap_content" |
6 |
android:textSize = "50px" |
7 |
android:textColor = "#FF0000" |
8 |
android:textStyle = "bold|italic" /> |
위와 같은 XML layout file을 java코드 내부에서 다음과 같이 적용.
String items[] = { "How", "to", "use", "ArrayAdapter?" };
ArrayAdapter <String> aa = new ArrayAdapter <String> (this,
R.layout.listview_item_layout_01,
items);
ListView 인스턴스.setAdapter(aa);
다음과 같이 ListView 아이템 text의 스타일이 변한다.
Selection 위젯의 아이템 view를 좀더 복잡한 형태의 view로 대체 하고 싶다면 ArrayAdapter를 상속해서 새로운 ArrayAdapter 클래스를 만들고 getView() 메소드를 오버라이딩 하면된다. 자세한 방법은 이곳으로 (013: ListView 꾸미기 & 최적화하기 2/2)
2. ListView 사용법
ListView의 상속 구조는 다음과 같다.
ListView의 구현은 Activity를 상속하는 방법과 ListActivity를 상속하는 방법 두 가지가 있다.
Activity를 상속하여 구현
Activity 기반 ListView (main.xml)
01 |
<? xml version = "1.0" encoding = "utf-8" ?> |
03 |
android:orientation = "vertical" |
04 |
android:layout_width = "fill_parent" |
05 |
android:layout_height = "fill_parent" > |
09 |
android:id = "@+id/textview" |
10 |
android:layout_width = "wrap_content" |
11 |
android:layout_height = "wrap_content" |
12 |
android:text = "No Selection" /> |
16 |
android:id = "@+id/listview" |
17 |
android:layout_width = "fill_parent" |
18 |
android:layout_height = "fill_parent" /> |
XML Layout 파일인 main.xml에서는 ListView element를 등록하고 listview 라고 identify했다.
또, ListView의 요소 중 선택된 아이템이 List 맨 위 아이템으로 옮겨오는 여부를 결정하는android:drawSelectorOnTop 속성을 false로 지정했다.
Activity 기반 ListView (MyListView_Activity.java)
01 |
package com.holim.test; |
02 |
import android.app.Activity; |
03 |
import android.os.Bundle; |
04 |
import android.view.View; |
05 |
import android.widget.AdapterView; |
06 |
import android.widget.ArrayAdapter; |
07 |
import android.widget.ListView; |
08 |
import android.widget.TextView; |
11 |
public class MyListView_Activity extends Activity |
12 |
implements AdapterView.OnItemClickListener { |
15 |
String items[] = { "111" , "222" , "333" }; |
23 |
/** Called when the activity is first created. */ |
25 |
public void onCreate(Bundle savedInstanceState) { |
26 |
super .onCreate(savedInstanceState); |
27 |
setContentView(R.layout.main); |
33 |
ArrayAdapter<String> aa = new ArrayAdapter<String>( this , |
34 |
android.R.layout.simple_list_item_1, |
38 |
lv = (ListView)findViewById(R.id.listview); |
44 |
lv.setOnItemClickListener( this ); |
47 |
tv = (TextView)findViewById(R.id.textview); |
52 |
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { |
54 |
tv.setText(items[position]); |
실행 화면은 다음과 같다.
ListActivity를 상속하여 구현
구현하려는 Activity의 view가 한 개의 ListView로 이루어져 있다면 이 방법이 훨씬 편하다.
ListActivity 기반 ListView (main.xml)
01 |
<? xml version = "1.0" encoding = "utf-8" ?> |
03 |
android:orientation = "vertical" |
04 |
android:layout_width = "fill_parent" |
05 |
android:layout_height = "fill_parent" > |
09 |
android:id = "@+id/textview" |
10 |
android:layout_width = "fill_parent" |
11 |
android:layout_height = "wrap_content" |
12 |
android:text = "No Selection" /> |
17 |
android:id = "@id/android:list" |
18 |
android:layout_width = "fill_parent" |
19 |
android:layout_height = "fill_parent" /> |
24 |
android:id = "@id/android:empty" |
25 |
android:layout_width = "wrap_content" |
26 |
android:layout_height = "wrap_content" |
27 |
android:text = "No Item" /> |
ListActivity 기반 ListView (MyListView_ListActivity.java)
01 |
package com.holim.test; |
02 |
import android.app.ListActivity; |
03 |
import android.os.Bundle; |
04 |
import android.view.View; |
05 |
import android.widget.ArrayAdapter; |
06 |
import android.widget.ListView; |
07 |
import android.widget.TextView; |
09 |
public class MyListView_ListActivity extends ListActivity { |
12 |
String items[] = { "111" , "222" , "333" }; |
17 |
/** Called when the activity is first created. */ |
19 |
public void onCreate(Bundle savedInstanceState) { |
20 |
super .onCreate(savedInstanceState); |
21 |
setContentView(R.layout.main); |