티스토리 뷰
Android Expandable 예제에 이어서 Expandable Custom 예제를 작성해보았습니다. 지난번과는 다른 데이터를 사용하였고, 결과화면의 차이는 없습니다. 첫 번째에 올렸던 기본예제는 아래 링크를 통해 확인 가능합니다.
Custom 하기
이번 예제는 제목 그대로 Custom을 하였습니다. Expandable을 커스텀하기 위한 방법은 간단합니다.
BaseExpandableListAdapter를 상속받아서 커스텀하면 됩니다.
BaseExpandableListAdapter API 페이지
http://developer.android.com/reference/android/widget/BaseExpandableListAdapter.html
ExpandableListAdapter API 페이지
http://developer.android.com/reference/android/widget/ExpandableListAdapter.html
BaseExpandableListAdapter Public Mehtod
BaseExpandableListAdapter은 ListView와는 다르게 Child와 Group 2가지로 구분이 됩니다. 그렇기 때문에 2가지의 다른 메소드가 아래와 같이 정의 되어 있습니다. 그렇기에 아래 메소드 중 화면에 표시하는 관련 Method는 모두 작성해주셔야 합니다. 사용해야 할 Method는 별도로 체크하겠습니다.
- 기본적으로 구현해야 하는 내용을 구현여부에 V 했습니다.
구현여부  | Type | Method Name  | 
abstract boolean  | 
areAllItemsEnabled()  | 
|
V  | abstract Object  | 
 getChild(int groupPosition, int childPosition)  | 
V  | abstract long |  getChildId(int groupPosition, int childPosition)  | 
V  | abstract View |  getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent)  | 
V  | abstract int |  getChildrenCount(int groupPosition)  | 
| abstract long |  getCombinedChildId(long groupId, long childId)  | |
| abstract long |  getCombinedGroupId(long groupId) 특정 Group의 아이디 값을 가져옵니다.  | |
V  | abstract Object |  getGroup(int groupPosition)  | 
V  | abstract int |  getGroupCount() Group의 Count를 Return 합니다.  | 
V  | abstract long |  getGroupId(int groupPosition)  | 
V  | abstract View |  getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)  | 
V  | abstract boolean |  hasStableIds()  | 
V  | abstract boolean |  isChildSelectable(int groupPosition, int childPosition)  | 
| abstract boolean | isEmpty() | |
| abstract void |  onGroupCollapsed(int groupPosition)  | |
| abstract void |  onGroupExpanded(int groupPosition) Group이 확장될 경우 호출합니다.  | |
| abstract void | registerDataSetObserver(DataSetObserver observer) | |
| abstract void | unregisterDataSetObserver(DataSetObserver observer) | 
V 표시가된 Method들이 기본적으로 구현되어야 하며, 나머지는 선택적으로 구현하시면 됩니다.
구현 내용
구현내용은 BaseExpandableAdapter를 상속받아서 구현하였습니다. API를 보시면 아시겠지만 BaseExpandableAdapter를 상속을 받지만 실제로는 ExpandableAdapter에서 해당 Method의 내용을 볼 수 있습니다.
저는 간단하게 휴대폰 OS 별로 휴대폰의 종류를 작성해보는 Custom ExpandableListView를 작성해보았습니다. 그리고 이미지 View를 사용했는데 기본 아이콘을 화면에 표시하였습니다.
주요 소스코드
MainActivity.java - 메인 엑티비티
ExpandableListView list = (ExpandableListView)findViewById(R.id.list); //create Data list.setAdapter(new ExpandableAdapter(this, createData()));
phoneData.java - 제가 사용하기 위해 구현한 Data 클래스
public class phoneData {
	String OS;
	ArrayList<String> PhoneType;
	
	public phoneData(String os, ArrayList<String> phoneType) {
		OS = os;
		PhoneType = phoneType;
	}
}
ExpandableAdapter.java - BaseExpandableAdatper를 상속받아 구현한 클래스
public class ExpandableAdapter extends BaseExpandableListAdapter {
	Context mContext;
	ArrayList<phoneData> mPhoneData;
	
	public ExpandableAdapter(Context context, ArrayList<phoneData> phone) {
		mContext = context;
		mPhoneData = phone; 
	}
	@Override
	public Object getChild(int groupPosition, int childPosition) {
		// TODO Auto-generated method stub
		return mPhoneData.get(groupPosition).PhoneType.get(childPosition);
	}
	@Override
	public long getChildId(int groupPosition, int childPosition) {
		// TODO Auto-generated method stub
		return childPosition;
	}
	//ChildView에 데이터 뿌리기 
	@Override
	public View getChildView(int groupPosition, int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {
		View view;
		if(convertView == null) {
			view = getChildGenericView();
		} else {
			view = convertView;
		}
		
		TextView text = (TextView)view.findViewById(android.R.id.text1);
		text.setText(mPhoneData.get(groupPosition).PhoneType.get(childPosition));
		return view;
	}
	@Override
	public int getChildrenCount(int groupPosition) {
		return mPhoneData.get(groupPosition).PhoneType.size();
	}
	@Override
	public Object getGroup(int groupPosition) {
		return mPhoneData.get(groupPosition);
	}
	@Override
	public int getGroupCount() {
		return mPhoneData.size();
	}
	@Override
	public long getGroupId(int groupPosition) {
		return groupPosition;
	}
	//GroupView에 데이터 뿌리
	@Override
	public View getGroupView(int groupPosition, boolean isExpanded,
			View convertView, ViewGroup parent) {
		
		View view;
		if(convertView == null) {
			view = getParentGenericView();
		} else {
			view = convertView;
		}
		
		ImageView img = (ImageView)view.findViewById(R.id.img);
		img.setImageResource(mContext.getResources().getIdentifier("ic_launcher", "drawable", mContext.getPackageName()));
		TextView text = (TextView)view.findViewById(R.id.text);
		text.setText(mPhoneData.get(groupPosition).OS);
		return view;
	}
	@Override
	public boolean hasStableIds() {
		// TODO Auto-generated method stub
		return false;
	}
	
	@Override
	public boolean areAllItemsEnabled() {
		// TODO Auto-generated method stub
		return super.areAllItemsEnabled();
	}
	@Override
	public boolean isChildSelectable(int groupPosition, int childPosition) {
		// TODO Auto-generated method stub
		return false;
	}
	
	//Child의 View의 XML을 생성 
	public View getChildGenericView() {
		LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View view = inflater.inflate(android.R.layout.simple_expandable_list_item_1, null);
		return view;
	}
	
	//Parent(Group)의 View의 XML을 생성 
	public View getParentGenericView() {
		LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View view = inflater.inflate(R.layout.simple_expandable_list_item_1, null);
		return view;
	}
}
Custom ListView xml - 리스트 뷰의 Custom
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
	    android:id="@+id/text"
	    android:layout_width="wrap_content"
	    android:layout_height="?android:attr/listPreferredItemHeight"
	    android:paddingStart="?android:attr/expandableListPreferredItemPaddingLeft"
	    android:gravity="center_vertical"
	    android:layout_weight="1" />
    <ImageView 
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="?android:attr/listPreferredItemHeight"
        android:scaleType="centerInside"
        android:layout_weight="0" />
</LinearLayout>
결과 화면
지난번에 작성한 것과는 내용만 다르고, Custom을 했다는것 말곤 전혀 차이가 없습니다. ExpandableListView 역시 UI커스텀도 가능합니다. 단 기본적으로 지원해주는 adapter를 사용하시면 커스텀 UI를 사용할 수 없고 위와 같이 구현하셔야 합니다. 이상으로 이번 글은 마치겠습니다. 역시 소스코드는 아래 주소로 다운로드 받으시면 됩니다.
소스코드 다운로드
'Android Develop' 카테고리의 다른 글
| Android Settings를 통한 AirplaneMode 예제 코드 (4) | 2013.02.02 | 
|---|---|
| ListView에 Swipe to Dismiss 적용하기(ICS이상에서 있는 Swipe 기능) (2) | 2013.01.26 | 
| ExpandableListView 단순 예제 (15) | 2013.01.16 | 
| Android Parcelable 인터페이스 구현 (2) | 2013.01.15 | 
| 3단계로 간단하게 Android 개발 환경 만들기(Android Developer Tools) (2) | 2012.12.01 | 
댓글