ExpandableListViewをカスタマイズするサンプルを作ってみた
ExpandableListViewの各行の表示を自分でカスタマイズしたレイアウトで実装したサンプルプログラムを作りました。
私の勉強メモです。
Androidに元々用意されているリスト表示形式では、1行に1項目か2項目しか表示できませんが、
リストの1行に当たる部分をXMLファイルに定義することで、様々な表現ができるようになります。
参考にしたのはこれらのサイト様です。いつもお世話になってます。本当にありがとうございます。
Android Expandable List のビューをカスタマイズ
シェフのアプリ開発秘話〜技術的要素を添えて〜
サンプルはこのようなイメージになります。
いまいちわかりにくいのですが、グループのView、子要素のViewを独自にxmlで指定しています。
テキストサイズを大きくしたり太字にしたりしています。
行が変わると背景が交互に黒とグレーになるようにプログラムから動的に指定しています。
サンプルの構成は
◯MyExpandableListAdapter.java
ExpandableListViewを表示します。
子要素がクリックされたら、内容をToastで表示します。
インナークラスに MyExpandableListAdapterInner.java を持っており、ここでアダプターに要素をセットしています。
◯expandablegroupview.xml
グループのView一行分のレイアウトです。
◯expandablechildview.xml
子要素のView一行分のレイアウトです。
◯AndroidManifest.xml
では、レイアウトファイルのサンプルから
res/layout/expandablegroupview.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/GroupLinearLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:paddingLeft="30dp" > <TextView android:id="@+id/GroupTextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:layout_margin="10sp" android:textSize="20sp" android:textStyle="bold" /> </LinearLayout>
res/layout/expandablechildview.xml
<?xml version="1.0" encoding="utf-8"?> <!-- リスト1行分のレイアウト --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:id="@+id/ChildLinearLayout" > <TextView android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:layout_margin="10sp" android:textSize="20sp" android:textStyle="bold" /> <TextView android:id="@+id/TextView02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10sp" android:layout_gravity="left" /> </LinearLayout>
src/MyExpandableListAdapter.java
package com.sakurafish.android.sample; import android.app.ExpandableListActivity; import android.content.Context; import android.graphics.Color; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.ExpandableListAdapter; import android.widget.ExpandableListView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; public class MyExpandableListAdapter extends ExpandableListActivity { ExpandableListAdapter mAdapter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // インナークラスでアダプターの内容をセット mAdapter = new MyExpandableListAdapterInner(); // アダプターをExpandableListViewにセット setListAdapter(mAdapter); } @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { // 子要素がクリックされたら内容をToastで表示する Object o = mAdapter.getChild(groupPosition, childPosition); Toast.makeText(getApplicationContext(), o.toString(), Toast.LENGTH_SHORT).show(); return super.onChildClick(parent, v, groupPosition, childPosition, id); } /*** * アダプタークラス */ public class MyExpandableListAdapterInner extends BaseExpandableListAdapter { // @formatter:off private final String[] groups = {"Group1", "Group2", "Group3"}; private final String[][][] children = { {{"Group1 Child1", "Child text1"}, {"Group1 Child2", "Child text2"}, {"Group1 Child3", "Child text3"}}, {{"Group2 Child1", "Child text1"}}, {{"Group3 Child1", "Child text1"}, {"Group3 Child2", "Child text2"}, {"Group3 Child3", "Child text3"}, {"Group3 Child4", "Child text4"}, {"Group3 Child5", "Child text5"}} }; // @formatter:on /** レイアウトをインフレートするための変数 */ private LayoutInflater layoutInflater = (LayoutInflater) getApplicationContext() .getSystemService(Context.LAYOUT_INFLATER_SERVICE);; @Override public Object getChild(int groupPosition, int childPosition) { return children[groupPosition][childPosition][0]; } /*** * 子要素を返す(オーバーロード) * * @param groupPosition * @param childPosition * @param textPosition * @return */ public String getChild(int groupPosition, int childPosition, int textPosition) { return children[groupPosition][childPosition][textPosition]; } @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } @Override public int getChildrenCount(int groupPosition) { return children[groupPosition].length; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { // 子要素のViewを作る // convertViewがnullの時だけインフレートする(1行ごとに呼ばれるので使いまわす) if (convertView == null) { convertView = layoutInflater.inflate(R.layout.expandchildview, null); } // 子要素の現在位置が奇数の場合はグレー、偶数の場合は黒を背景にセットする LinearLayout linearLayout = (LinearLayout) convertView.findViewById(R.id.ChildLinearLayout); if ((childPosition % 2) != 0) { linearLayout.setBackgroundColor(Color.DKGRAY); } else { linearLayout.setBackgroundColor(Color.BLACK); } TextView textView1 = (TextView) convertView.findViewById(R.id.TextView01); TextView textView2 = (TextView) convertView.findViewById(R.id.TextView02); textView1.setText(getChild(groupPosition, childPosition, 0).toString()); textView2.setText(getChild(groupPosition, childPosition, 1).toString()); return convertView; } @Override public Object getGroup(int groupPosition) { return groups[groupPosition]; } @Override public int getGroupCount() { return groups.length; } @Override public long getGroupId(int groupPosition) { return groupPosition; } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { // グループのViewを作る処理 // convertViewがnullの時だけインフレートする(1行ごとに呼ばれるので使いまわす) if (convertView == null) { convertView = layoutInflater.inflate(R.layout.expandgroupview, null); } // 子要素の現在位置が偶数の場合はグレー、奇数の場合は黒を背景にセットする LinearLayout linearLayout = (LinearLayout) convertView .findViewById(R.id.GroupLinearLayout); if ((groupPosition % 2) == 0) { linearLayout.setBackgroundColor(Color.DKGRAY); } else { linearLayout.setBackgroundColor(Color.BLACK); } TextView textView = (TextView) convertView.findViewById(R.id.GroupTextView01); textView.setText(getGroup(groupPosition).toString()); return convertView; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } @Override public boolean hasStableIds() { return true; } } }
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.sakurafish.android.sample" android:versionCode="2" android:versionName="1.0" > <uses-sdk android:minSdkVersion="4" /> <application android:debuggable="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".MyExpandableListAdapter" android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>