Android

ListView 꾸미기

너구리V 2011. 5. 23. 22:04

출처 :http://tigerwoods.tistory.com/14

1. XML을 이용해 꾸미기

스마트폰의 제한적인 스크린 사이즈 때문에 List위젯들(ListView, spinner등)의 중요성은 아주 크다.

list 위젯의 생김새를 결정하는 것은 전적으로 어떤 구성의 Adapter를 해당 list위젯에 연결하느냐에 달려있다.

다음 예는 전 장에서 사용한 썰렁한 text 대신, 아이콘+Text로 이루어진 행(row) xml layout 을 ListView에 적용한 예이다.

 

접기

XML을 이용한 List 꾸미기 (main.xml)

01 <?xml version="1.0" encoding="utf-8"?>
02 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03     android:orientation="vertical"
04     android:layout_width="fill_parent"
05     android:layout_height="fill_parent" >
06     <!-- ListView에서 클릭되는 Item 확인 용 TextView -->
07     <TextView
08         android:id="@+id/selection"
09         android:layout_width="wrap_content"
10         android:layout_height="wrap_content"
11         android:text="No Selection"
12         android:textColor="#FF0000"
13         android:textSize="20px" />
14     <!-- ListActivity의 기본 ListView로 지정 -->
15     <ListView
16         android:id="@id/android:list"
17         android:layout_width="fill_parent"
18         android:layout_height="fill_parent" />
19      
20     <!-- ListView가 비어있을때 표현되는 TextView -->
21     <TextView
22         android:id="@id/android:empty"
23         android:layout_width="wrap_content"
24         android:layout_height="wrap_content"
25         android:layout_gravity="center"
26         android:text="No Item" />
27 </LinearLayout>

 

XML을 이용한 List 꾸미기 (row.xml)

01 <?xml version="1.0" encoding="utf-8"?>
02 <!-- ListView의 행(Row)마다 적용될 layout -->
03 <LinearLayout
04     xmlns:android="http://schemas.android.com/apk/res/android"
05     android:layout_width="wrap_content"
06     android:layout_height="wrap_content"
07     android:orientation="horizontal" >
08     <!-- 각 행(row)의 시작은 ImageView -->
09     <ImageView
10         android:id="@+id/icon"
11         android:src="@drawable/tiger"
12         android:layout_width="30px"
13         android:layout_height="30px"
14         android:layout_gravity="center_vertical" />
15      
16     <!-- ImageView 다음 올  설명 text를 위한 TextView -->
17     <TextView
18         android:id="@+id/label"
19         android:layout_width="fill_parent"
20         android:layout_height="wrap_content"
21         android:layout_gravity="center_vertical"
22         android:textSize="30px" />
23 </LinearLayout>

 

XML을 이용한 List 꾸미기 (MyFancyListView01.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;
08 public class MyFancyListView01 extends ListActivity {
09     TextView tv;
10     String[] items={ "Android", "iPhone", "UI", "Java", "SDK",
11                     "Adapter", "List", "This", "is", "Fun" };
12      
13     /** Called when the activity is first created. */
14     @Override
15     public void onCreate(Bundle savedInstanceState) {
16         super.onCreate(savedInstanceState);
17         setContentView(R.layout.main);
18          
19         // String형을 data로 하는 ArrayAdapter 선언/초기화
20         // this: context to use
21         // R.layout.row: 한줄 한줄 표현할 item을 위한 view. 여기서는 \res\layout\row.xml 을 지정함.
22         // R.id.lable: 위 xml 문서에서 text를 담당할 요소(TextView)의 id.
23         // items: ListView에 표현될 data
24         ArrayAdapter<String> aa = new ArrayAdapter<String> (this,
25                                                             R.layout.row,
26                                                             R.id.label,
27                                                             items);
28         // 위에 정의된 aa를 본 ListActivity의 아답터로 설정
29         setListAdapter(aa);
30          
31         tv = (TextView)findViewById(R.id.selection);
32     }
33      
34     public void onListItemClick(ListView l, View v, int position, long id) {
35         tv.setText(items[position] + " 클릭됨");
36     }
37 }

 

접기

 

다음은 실행 화면이다.

 

 

2. Java 코드 내부에서 동적으로 꾸미기

위 단락의 예제와 같이 별도의 XML layout파일을 아답터에 적용 하고 List에 아답터를 연결하여 list의 각 row의 생김새를 바꾸는 작업은 어렵지 않다.

하지만, 다음과 같은 경우에는 XML layout 파일 기반의 방법은 사용이 어렵다.

  • 모든 행(row)가 일률적인 layout으로 구성되지 않는 List.
  • 모든 row가 일률적 layout이라도, layout을 구성하는 content가 제 각각일 때. (eg. 각 row마다 icon이 다를 때 등)

 

이런 경우 Adapter를 상속하는 커스텀 adapter를 만들고 getView()를 오버라이딩해서 문제를 해결할 수 있다.

 

접기

Java code 기반의 List 꾸미기 (main.xml)

01 <?xml version="1.0" encoding="utf-8"?>
02 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03     android:orientation="vertical"
04     android:layout_width="fill_parent"
05     android:layout_height="fill_parent" >
06     <!-- ListView에서 클릭되는 Item 확인 용 TextView -->
07     <TextView
08         android:id="@+id/selection"
09         android:layout_width="wrap_content"
10         android:layout_height="wrap_content"
11         android:text="No Selection"
12         android:textColor="#FF0000"
13         android:textSize="20px" />
14     <!-- ListActivity의 기본 ListView -->
15     <ListView
16         android:id="@id/android:list"
17         android:layout_width="fill_parent"
18         android:layout_height="fill_parent" />
19      
20     <!-- ListView가 비어있을때(empty) 표현되는 TextView -->
21     <TextView
22         android:id="@id/android:empty"
23         android:layout_width="wrap_content"
24         android:layout_height="wrap_content"
25         android:layout_gravity="center"
26         android:text="No Item" />
27 </LinearLayout>

 

Java code 기반의 List 꾸미기 (row.xml)

01 <?xml version="1.0" encoding="utf-8"?>
02 <!-- ListView의 행(Row)마다 적용될 layout -->
03 <LinearLayout
04     xmlns:android="http://schemas.android.com/apk/res/android"
05     android:layout_width="wrap_content"
06     android:layout_height="wrap_content"
07     android:orientation="horizontal" >
08     <!-- 각 행(row)의 시작은 ImageView -->
09     <ImageView
10         android:id="@+id/icon"
11         android:src="@drawable/tiger"
12         android:layout_width="30px"
13         android:layout_height="30px"
14         android:layout_gravity="center_vertical" />
15      
16     <!-- ImageView 오른편에 표시 될 Text -->
17     <TextView
18         android:id="@+id/label"
19         android:layout_width="fill_parent"
20         android:layout_height="wrap_content"
21         android:layout_gravity="center_vertical"
22         android:textSize="30px" />
23 </LinearLayout>

 

Java code 기반의 List 꾸미기 (MyFancyListView02.java)

01 package com.holim.test;
02 import android.app.Activity;
03 import android.app.ListActivity;
04 import android.content.Context;
05 import android.os.Bundle;
06 import android.view.LayoutInflater;
07 import android.view.View;
08 import android.view.ViewGroup;
09 import android.widget.ArrayAdapter;
10 import android.widget.ImageView;
11 import android.widget.ListView;
12 import android.widget.TextView;
13 public class MyFancyListView02 extends ListActivity {
14      
15     // ListView에 뿌릴 Data
16     String[] items={ "Android", "iPhone", "UI", "Java", "SDK",
17                         "Adapter", "List", "This", "is", "Fun" };
18     TextView tv;
19     /** Called when the activity is first created. */
20     @Override
21     public void onCreate(Bundle savedInstanceState) {
22         super.onCreate(savedInstanceState);
23         setContentView(R.layout.main);
24          
25         // 커스텀 ArrayAdapter 선언/초기화.
26         MyArrayAdapter aa = new MyArrayAdapter(this);
27          
28         // 본 Activity의 아답터로 aa 지정.
29         setListAdapter(aa);
30          
31         tv = (TextView)findViewById(R.id.selection);
32     }
33      
34     // ListView의 아이템이 클릭되면 호출되는 callback.
35     public void onListItemClick(ListView l, View v, int position, long id) {
36         tv.setText(items[position]);
37     }
38      
39     // ArrayAdapter에서 상속받는 커스텀 ArrayAdapter 정의.
40     class MyArrayAdapter extends ArrayAdapter {
41         // 생성자 내부에서 초기화
42         Context context;
43          
44         // 생성자
45         MyArrayAdapter(Context context) {
46             super(context, R.layout.row, items);
47              
48             // instance 변수(this.context)를 생성자 호출시 전달받은 지역 변수(context)로 초기화.
49             this.context = context;
50         }
51          
52         // ListView에서 각 행(row)을 화면에 표시하기 전 호출됨.
53         public View getView(int position, View convertView, ViewGroup parent){
54             // LayoutInflater의 객체 inflater를 현재 context와 연결된 inflater로 초기화.
55             LayoutInflater inflater = ((Activity)context).getLayoutInflater();
56              
57             // inflator객체를 이용하여 \res\laout\row.xml 파싱
58             View row = (View)inflater.inflate(R.layout.row, null);
59              
60             // TextView 객체 label을 row 객체 내부에 있는 R.id.label로 초기화
61             TextView label = (TextView)row.findViewById(R.id.label);
62              
63             // label에 텍스트 설정.
64             label.setText(items[position]);
65              
66             // items 배열에서 현제 처리중인 위치의 text 길이가 4 이상이면
67             // 아이콘을 'x' 마크로 변경. 4미만일때는 아무 변화없이 xml layout 초기값인 '첵크'마크 사용됨.
68             if(items[position].length()>4) {
69                  
70                 // 이미지뷰 객체 icon을 row내부에 정의된 R.id.icon으로 초기화.
71                 ImageView icon = (ImageView)row.findViewById(R.id.icon);
72                  
73                 // icon 객체가 표현할 리소스를 'x' 마크(R.drawable.delete)로 지정.
74                 icon.setImageResource(R.drawable.delete);
75                  
76             }
77              
78             // 커스터마이징 된 View 리턴.
79             return row;
80         }
81     };
82 }

 

접기


위 소스에서 나오는 LayoutInflater 클래스는 쉽게 말해서 XML parser이다.

XML형태로 제공된 layout(\res\layout\row.xml)을 View 객체로 구조화 하고 View 객체가 포함하는 여러 위젯 (여기서는 LinearLayout, ImageView, TextView)을 update 함으로 각 행(row)에 대한 layout을 커스터마이징 한다.

 

실행 결과는 다음과 같다. 글자수가 4자 이상인 row의 아이콘만 x로 바뀐 것을 볼 수 있다.

 

반응형

'Android' 카테고리의 다른 글

레이아웃 %로 구성  (0) 2011.03.23