확장 리스트 뷰는 분류 별로 데이타를 그룹화 하는 데 사용 됩니다. 이 뷰는 사용자가 헤더 터치 시 그룹들을 펼치거나 접을 수 있도록 해 줍니다.
만약 이 리스트 뷰에 대해서 잘 모른다면 먼저 #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 만 가능 한 것 같습니다. 수정하기 보다는 이를 지원하는 오픈소스를 찾아 보는 것이 정신 건강 상 좋을 것으로 판단 되기도 하는 데요....
다른 오픈 소스는 다음과 같습니다.
이상.
'모바일프로그래밍 > 안드로이드' 카테고리의 다른 글
[ProGuard] 안드로이드 애플리케이션의 최적화, 난독화 및 최소화 (0) | 2023.01.14 |
---|---|
데이터베이스 동시 접근 – Sqlite (0) | 2023.01.13 |
안드로이드 APK 분석 참고 문서 (0) | 2023.01.04 |
안드로이드 이해하기 - 첫 걸음 떼기 (0) | 2023.01.02 |
Android Notification 이란 (0) | 2022.12.17 |