하지만 그 경우에도 ListView의 각 엔트리에 한개의 값만 넣을 수 있었고 텍스트 뷰 이외를 사용하지 못했었다. 그래서 이번 포스팅에서는 ArrayAdapter를 상속받은 커스텀 ArrayAdapter를 만들고 getView() 메소드를 오버라이드 하여 TextView 외에 ImageView도 같이 집어넣어 보도록 하겠다.
간단한 주소록을 보여주는 앱을 만들것이므로 먼저 String 대신 주소록 엔트리를 위한 클래스를 정의한다.
/src/.../ABEntry.java
package app.arsviator;
public class ABEntry {
private String name;
private String phoneNo;
private int photo;
public ABEntry(String _name, String _pn, int _photo) {
this.name = _name;
this.phoneNo = _pn;
this.photo = _photo;
}
public String getName() {
return name;
}
public String getPhoneNo() {
return phoneNo;
}
public int getPhotoId() {
return photo;
}
}
위의 소스코드를 src 디렉토리에 ABEntry.java 란 이름으로 저장해주면 된다.
그 다음은 ListView의 각 엔트리를 위한 레이아웃을 정의한다.
여기서는 위와 같이 레이아웃을 정의했다.
/res/layout/entry.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:paddingTop="5px"
android:paddingBottom="5px"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ImageView android:id="@+id/ePhoto"
android:layout_width="48px"
android:layout_height="48px"
android:src="@drawable/nophoto" />
<LinearLayout android:orientation="vertical"
android:paddingLeft="10px"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/eName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="22sp" />
<TextView android:id="@+id/ePhoneNo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="16sp" />
</LinearLayout>
<TextView android:id="@+id/eNull"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
위의 소스를 /res/layout/entry.xml 로 저장해주면 된다.
private class ABArrayAdapter extends ArrayAdapter<ABEntry> {
private ArrayList<ABEntry> items;
private int rsrc;
public ABArrayAdapter(Context ctx, int rsrcId, int txtId, ArrayList<ABEntry> data) {
super(ctx, rsrcId, txtId, data);
this.items = data;
this.rsrc = rsrcId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = li.inflate(rsrc, null);
}
ABEntry e = items.get(position);
if (e != null) {
((TextView)v.findViewById(R.id.eName)).setText(e.getName());
((TextView)v.findViewById(R.id.ePhoneNo)).setText(e.getPhoneNo());
if (e.getPhotoId() != -1) {
((ImageView)v.findViewById(R.id.ePhoto)).setImageResource(e.getPhotoId());
} else {
((ImageView)v.findViewById(R.id.ePhoto)).setImageResource(R.drawable.nophoto);
}
}
return v;
}
}
}
private ArrayList<ABEntry> items;
private int rsrc;
public ABArrayAdapter(Context ctx, int rsrcId, int txtId, ArrayList<ABEntry> data) {
super(ctx, rsrcId, txtId, data);
this.items = data;
this.rsrc = rsrcId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = li.inflate(rsrc, null);
}
ABEntry e = items.get(position);
if (e != null) {
((TextView)v.findViewById(R.id.eName)).setText(e.getName());
((TextView)v.findViewById(R.id.ePhoneNo)).setText(e.getPhoneNo());
if (e.getPhotoId() != -1) {
((ImageView)v.findViewById(R.id.ePhoto)).setImageResource(e.getPhotoId());
} else {
((ImageView)v.findViewById(R.id.ePhoto)).setImageResource(R.drawable.nophoto);
}
}
return v;
}
}
}
이번 포스팅의 가장 핵심 부분인 ArrayAdapter를 상속받은 ABArrayAdapter 클래스이다. 오버라이드 한 getView() 안에서 우선 LayoutInflator를 사용해서 /res/layout/entry.xml을 View로 inflate한다.
LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = li.inflate(rsrc, null);
그 다음 ABEntry 오브젝트에 있는 이름, 전화번호, 사진을 각각 eName, ePhoneNo, ePhoto에 넣어준다. 사진이 없는 경우(e.getPhotoId() == -1)는 디폴트 사진(여기서는 강아지 그림)을 표시하고 사진이 지정되어 있는 경우는 /res/drawable에 있는 사진을 가져오도록 해 놓았다.
CustomAA.java의 전체 소스는 다음과 같다.
펼쳐두기..
그 이외에 필요한 파일은 다음과 같다.
펼쳐두기..
프로젝트에 필요한 이미지 파일은 아래 zip 파일을 다운받아 res 디렉토리에서 압축을 풀면 drawable디렉토리 아래에 만들어진다.
실행하면 위에서같이 간단한 주소록이 나오게 되고 그 중 한 항목을 선택하면 전화를 걸거나 항목을 삭제할 수 있도록 AlertDialog가 나오게 된다.
전화를 걸기 위해서는 AndroidManifest.xml 파일에 CALL_PHONE permission을 추가하는걸 잊으면 안된다.
펼쳐두기..