안드로이드 확장 리스트 뷰에 대한 자습서

2023. 1. 12. 19:07모바일프로그래밍/안드로이드

728x90
 
 

http://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/

 

www.androidhive.info

확장 리스트 뷰는 분류 별로 데이타를 그룹화 하는 데 사용 됩니다. 이 뷰는 사용자가 헤더 터치 시 그룹들을 펼치거나 접을 수 있도록 해 줍니다.

 

만약 이 리스트 뷰에 대해서 잘 모른다면 먼저 #Android #ListView #Tutorial 를 참고 하십시오

https://www.androidhive.info/2011/10/android-listview-tutorial/

새로운 프로젝트를 만들어서 시작해 봅시다.

 

1. 이클립스 IDE에서 File ⇒ Android Application Project를 생성한 후 자신만의 내용으로 채워넣고 새로운 프로젝트를 만들어 줍니다. 내 메인 액티비티 이름은 MainActivity.java 로 하였습니다.

 

2. 확장 리스트 뷰를 만들기 위해서, 우리는 레이아웃 파일들이 필요 합니다. 첫 번째 레이아웃은 메인 리스트뷰가 되고, 두번째는 리스트뷰 그룹 아이템 그리고 자식 리스트 뷰 아이템을 위한 것입니다.

activity_main.xml 을 열고 ExpandableListView 엘리먼트를 추가 합니다.

 

========== activity_main.xml =========================

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	android:orientation="vertical"
	android:background="#f4f4f4" >

	<ExpandableListView
		android:id="@+id/lvExp"
		android:layout_height="match_parent"
		android:layout_width="match_parent"/>
</LinearLayout>
 

3. 뷰 그룹 헤더를 위해서 또 다른 xml 레이아웃을 생성합니다. list_group.xml 이라는 이름을 xml 파일을 생성 하였고 다음 코드를 작성습니다.

 

========== list_group.xml =========================

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content"
	android:orientation="vertical"
	android:padding="8dp"
	android:background="#000000">
	<TextView
		android:id="@+id/lblListHeader"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
		android:textSize="17dp"
		android:textColor="#f9f93d" />
</LinearLayout>
 

 

4.자식 리스트 아이템을 위해서 list_item.xml라는 이름의 파일을 하나 더 생성 합니다. 이는 간단한 TextView 엘리먼트를 담고 있을 것입니다.

 

========== list_item.xml =========================

<?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="55dip"
	android:orientation="vertical" >

<TextView
	android:id="@+id/lblListItem"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content"
	android:textSize="17dip"
	android:paddingTop="5dp"
	android:paddingBottom="5dp"
	android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft" />

</LinearLayout>
 

 

5.리스트 뷰를 생성 하기 위해서 커스텀 어댑터 클래스를 사용 할 것입니다. 새로운 ExpandableListAdapter.java 라는 이름의 클래스를 생성하고 BaseExpandableListAdapter 에서 상속 받습니다.

getGroupView() - 리스트 그룹 헤더를 위한 뷰를 리턴한다.

getChildView() - 자식 리스트 아이템을 위한 뷰를 리턴한다.

 

>> ExpandableListAdapter.java

package info.androidhive.expandablelistview;

import java.util.HashMap;
import java.util.List;
import android.content.Context;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;

public class ExpandableListAdapter extends BaseExpandableListAdapter {

	private Context _context;
	private List<String> _listDataHeader; // header titles
	// child data in format of header title, child title
	private HashMap<String, List<String>> _listDataChild;
	
	public ExpandableListAdapter(Context context, List<String> listDataHeader,
		HashMap<String, List<String>> listChildData) {
		this._context = context;
		this._listDataHeader = listDataHeader;
		this._listDataChild = listChildData;
	}

	@Override
	public Object getChild(int groupPosition, int childPosititon) {
		return this._listDataChild.get(this._listDataHeader.get(groupPosition)).get(childPosititon);
	}
	
	@Override
	public long getChildId(int groupPosition, int childPosition) {
		return childPosition;
	}
	
	@Override
	
	public View getChildView(int groupPosition, final int childPosition,
		boolean isLastChild, View convertView, ViewGroup parent) {
	
		final String childText = (String) getChild(groupPosition, childPosition);
	
		if (convertView == null) {
			LayoutInflater infalInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			convertView = infalInflater.inflate(R.layout.list_item, null);
		}
	
		TextView txtListChild = (TextView) convertView.findViewById(R.id.lblListItem);
		txtListChild.setText(childText);
		return convertView;
	}
	
	@Override
	public int getChildrenCount(int groupPosition) {	
		return this._listDataChild.get(this._listDataHeader.get(groupPosition)).size();
	}
	
	@Override
	public Object getGroup(int groupPosition) {
		return this._listDataHeader.get(groupPosition);
	}
	
	@Override
	public int getGroupCount() {
		return this._listDataHeader.size();
	}
	
	@Override
	public long getGroupId(int groupPosition) {
		return groupPosition;
	}
	
	@Override
	public View getGroupView(int groupPosition, boolean isExpanded,
		View convertView, ViewGroup parent) {
		String headerTitle = (String) getGroup(groupPosition);
		
		if (convertView == null) {
			LayoutInflater infalInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			convertView = infalInflater.inflate(R.layout.list_group, null);
		}
		
		TextView lblListHeader = (TextView) convertView.findViewById(R.id.lblListHeader);
		lblListHeader.setTypeface(null, Typeface.BOLD);
		lblListHeader.setText(headerTitle);
		return convertView;
	}
	@Override
	public boolean hasStableIds() {
		return false;
	}
	@Override
	public boolean isChildSelectable(int groupPosition, int childPosition) {
		return true;
	}
}
 

 

6. 커스텀 어댑터 작업이 끝나면, MainActivity.java 파일을 열고 다음 코드를 작성합니다. 리스트 뷰에 필요 한 요구 데이타를 생성하였고 커스텀 어댑터로 이를 전달 하였습니다.

 

=> MainActivity.java

package info.androidhive.expandablelistview;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.ExpandableListView.OnGroupCollapseListener;
import android.widget.ExpandableListView.OnGroupExpandListener;
import android.widget.Toast;

public class MainActivity extends Activity {
	ExpandableListAdapter listAdapter;
	ExpandableListView expListView;
	List<String> listDataHeader;
	HashMap<String, List<String>> listDataChild;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		// get the listview
		expListView = (ExpandableListView) findViewById(R.id.lvExp);
		
		// preparing list data
		prepareListData();
		
		listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);
		
		// setting list adapter
		expListView.setAdapter(listAdapter);
	
	}
	
	/*
	* Preparing the list data
	*/
	private void prepareListData() {
		listDataHeader = new ArrayList<String>();
		listDataChild = new HashMap<String, List<String>>();
		
		// Adding child data
		listDataHeader.add("Top 250");
		listDataHeader.add("Now Showing");
		listDataHeader.add("Coming Soon..");
		
		// Adding child data
		List<String> top250 = new ArrayList<String>();
		top250.add("The Shawshank Redemption");
		top250.add("The Godfather");
		top250.add("The Godfather: Part II");
		top250.add("Pulp Fiction");
		top250.add("The Good, the Bad and the Ugly");
		top250.add("The Dark Knight");
		top250.add("12 Angry Men");
		
		List<String> nowShowing = new ArrayList<String>();
		nowShowing.add("The Conjuring");
		nowShowing.add("Despicable Me 2");
		nowShowing.add("Turbo");
		nowShowing.add("Grown Ups 2");
		nowShowing.add("Red 2");
		nowShowing.add("The Wolverine");
		
		List<String> comingSoon = new ArrayList<String>();
		comingSoon.add("2 Guns");
		comingSoon.add("The Smurfs 2");
		comingSoon.add("The Spectacular Now");
		comingSoon.add("The Canyons");
		comingSoon.add("Europa Report");
		
		listDataChild.put(listDataHeader.get(0), top250); // Header, Child data
		listDataChild.put(listDataHeader.get(1), nowShowing);
		listDataChild.put(listDataHeader.get(2), comingSoon);
	}
}
 

프로젝트를 실행해서 다음 결과가 나오는 지 확인 해야만 합니다.(주의 리스트뷰 그룹은 지금 구동되는 안드로이드 버전에 따라서 다르게 보일 수 있습니다.

 

위의 소스는 수정 없이는 2 depth 만 가능 한 것 같습니다. 수정하기 보다는 이를 지원하는 오픈소스를 찾아 보는 것이 정신 건강 상 좋을 것으로 판단 되기도 하는 데요....

 

다른 오픈 소스는 다음과 같습니다.

 

 

GitHub - Polidea/tree-view-list-android: Provide configurable tree view list for android devices

Provide configurable tree view list for android devices - GitHub - Polidea/tree-view-list-android: Provide configurable tree view list for android devices

github.com

 

 

GitHub - bmelnychuk/AndroidTreeView: AndroidTreeView. TreeView implementation for android

AndroidTreeView. TreeView implementation for android - GitHub - bmelnychuk/AndroidTreeView: AndroidTreeView. TreeView implementation for android

github.com

 

이상.

 

728x90