티스토리 뷰

ExpandableListView 란?

 Android ListView에는 ExpandableListView가 있습니다. ListView는 단순히 리스트를 뿌려주는 역할을 하고, ExpandableListView는 말그대로 확장기능을 제공합니다. 사용법은 조금 까다롭게 적용되어 있습니다. 단순히 ListView처럼 array.xml을 생성하여 리소스 아이디를 직접 적용할 수 없고, HashMap을 만들어서 적용해야 합니다. 당연히 Custom ExpandableListView도 가능합니다. Custom ExpandableListView는 추후에 알아보기로 하고, 이번에는 간단히 ExpandableListView를 생성하는 것을 작성해보겠습니다.

ExpandableListView는 ListView의 하위 속성입니다.


해당 소스코드 작성은 Android 4.2에서 하였습니다.


ExpandableListView API 홈페이지

   http://developer.android.com/reference/android/widget/ExpandableListView.html

ExpandableListAdapter API 홈페이지

   http://developer.android.com/reference/android/widget/ExpandableListAdapter.html

SimpleExpandableListAdapter API 홈페이지

   http://developer.android.com/reference/android/widget/SimpleExpandableListAdapter.html


ExpandableListAdapter의 생성자

ExpandableListAdapter를 생성하기 위한 메서드는 3가지가 있습니다.

SimpleExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData, int groupLayout, String[] groupFrom, int[] groupTo, List<? extends List<? extends Map<String, ?>>> childData, int childLayout, String[] childFrom, int[] childTo)
Constructor
SimpleExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData, int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, int[] groupTo, List<? extends List<? extends Map<String, ?>>> childData, int childLayout, String[] childFrom, int[] childTo)
Constructor
SimpleExpandableListAdapter(Context context, List<? extends Map<String, ?>> groupData, int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, int[] groupTo, List<? extends List<? extends Map<String, ?>>> childData, int childLayout, int lastChildLayout, String[] childFrom, int[] childTo)
Constructor

 위와 같은 3가지 속성을 제공합니다. 복잡해 보입니다. 그래서 아래 소스코드 내용 중에 주석을 달아두었으니 해당 내용을 참고하시는게 더 좋아보입니다.


구현 내용

 ExpandableListView를 이용하여 간단히 사전같이 만들어봤습니다. 데이터베이스를 활용하거나, xls등의 문서를 활용한다면 더 빠르게 만들 수 있겠지만 간단히 만든 예제이다 보니 ArrayList를 통해서 데이터를 생성하였습니다. 위의 생성자를 보시면 알겠지만 Resources ID가 들어갈 수 있는 공간이 없습니다. 모두 List로 된 데이터를 요구하고 있습니다. array.xml을 통한다고 하더라도 모두 변환을 해주어야 사용이 가능합니다.

 저는 데이터 저장을 위해서 ArrayList를 사용하였고, String, List로 저장하는 데이터와 사전 데이터는 String, String으로 구현하였습니다.


소스코드

DicType.java

 - 사전의 a, b, c 등의 구분을 위한 class를 정의하였습니다.

public class DicType {
	String Type;
	List<DicName> Array;
	
	public DicType(String type, List<DicName> array) {
		Type = type;
		Array = array;
	}
}

DicName.java

  - 사전의 구분에 따른 실제 데이터를 저장하기 위한 class 입니다. 영어 단어와 한국어 이름을 정의하였습니다.

public class DicName {
	String enName;
	String koName;
	
	public DicName(String en, String ko) {
		enName = en;
		koName = ko;
	}
}

MainActivity.java

 - 정의한 데이터의 내용을 제외하고, 실제로 사용된 내용만 작성하겠습니다. 전체 소스코드는 하단의 다운로드를 통해 받으실 수 있습니다.

//ExpandableListView를 찾는다.
ExpandableListView exList = (ExpandableListView)findViewById(R.id.expandablelist);
//사전의 Type을 저장할 List Map을 생성한다.
List<Map<String, String>> dicType = new ArrayList<Map<String, String>>();
//사전의 data를 저장할 List Map을 생성한다. List안에 List안에 Map의 형태를 뛴다.
List<List<Map<String, String>>> dicArrName = new ArrayList<List<Map<String, String>>>();
		
//List의 Map에 key와 데이터를 저장하기 위한 코드
for(int i=0;i<arrData.size();i++) {
	Map<String, String> type = new HashMap<String, String>();
	//key값과 데이터를 저장
	type.put("Type", arrData.get(i).Type);
	//dicType List에 HashMap을 저장
	dicType.add(type);
	
	List<Map<String, String>> arrName = new ArrayList<Map<String, String>>();
	for(int j=0;j<arrData.get(i).Array.size();j++) {
		Map<String, String> name = new HashMap<String, String>();
		name.put("enName", arrData.get(i).Array.get(j).enName);
		name.put("koName", arrData.get(i).Array.get(j).koName);
		arrName.add(name);
	}
	dicArrName.add(arrName);
}
		
ExpandableListAdapter adapter = new SimpleExpandableListAdapter(
	this,
	dicType, //화면에 뿌려줄 데이터를 호출
	//사용할 리스트뷰를 호출
	android.R.layout.simple_expandable_list_item_1,
	new String[] { "Type" }, //뿌려줄 값의 Hash의 key를 적어준다.
	new int[] { android.R.id.text1 }, //뿌려줄 TextView를 불러온다.
	//사용할 보조 데이터를 호출한다.
	dicArrName,
	android.R.layout.simple_expandable_list_item_2,
	//배열을 사용하여 호출 할 수 있다. 이 경우 View의 수와 꼭 맞게 적용해야 한다.
	new String[] { "enName", "koName" },
	//String의 수와 View의 수가 1:1이어야 한다.
	new int[] { android.R.id.text1, android.R.id.text2 }
);
//생성한 adapter를 List에 뿌려준다.
exList.setAdapter(adapter);

결과 화면

 android에서 기본적으로 제공해주는 simple_expandable_list_item_1과 simple_expandable_list_item_2를 사용하여 아래와 같은 화면을 보여주고 있습니다. simple_expandable_list_item_1은 단순 제목만 보여주고 simple_expandable_list_item_2는 제목과 부가 설명까지 보이게 됩니다.


소스코드 다운로드

   http://db.tt/WTnv4AcD


마무리

 String[]을 통해서도 동일하게 출력이 가능합니다. 클래스를 통해서 함께 관리하고 싶어서 위와 같이 class를 구성하였습니다. 데이터 처리방식과 ExpandableListView 사용법을 좀 더 익혀 좋은 코드를 작성하시기 바랍니다.





댓글