セクション毎の区切り用ビュー付きListView
参考
- Android - (ListView) 区切りフィールド付き+インデクス表示付きのスクロール | Dev. GrAFR
- インデクス表示付きのサンプル
実装するにあたり
- iOSのようにデフォルトで区切り用ビューを提供していない
- 普通のビューを作る感覚で区切り用ビューも作らなければいけない
- ルール決めした配列を渡すだけで区切り用ビュー表示までは自動でやってもらいたい
実装
listview_sep.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="wrap_content" android:paddingLeft="10px" android:background="#AAA" android:layout_width="fill_parent" android:orientation="vertical"> <TextView android:layout_height="wrap_content" android:textColor="#FFFFFF" android:text="タイトル" android:id="@+id/section_title" android:layout_width="fill_parent"> </TextView> </LinearLayout>
SeparateArrayAdapter.java
public class SeparateArrayAdapter extends ArrayAdapter<Object> { /** * String型かList型かで区切りか否かを判定するため原型を保持しておく */ private List<Object> objects = null; private LayoutInflater inflater = null; /** * 第三引数には * ・セクションタイトル(String) * ・セクション表示用アイテム(List<Object>) * がセクション毎に並んでいるList<Object>を渡すこと * @param context * @param textViewResourceId * @param objects */ @SuppressWarnings("unchecked") public SeparateArrayAdapter(Context context, int textViewResourceId, List<Object> objects) { super(context, textViewResourceId, new ArrayList<Object>()); inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.objects = objects; // getCount(), getItem()を上書かなくてもいいようここで整形 for (Object obj : objects) { if (obj instanceof String) { add(obj); } else { for (Object item : (List<Object>) obj) { add(item); } } } } @Override public View getView(int position, View convertView, ViewGroup parent) { Object obj = getItem(position); // 区切りでない if (isEnabled(position)) { convertView = getCustomView(obj, convertView); } // 区切り else { convertView = inflater.inflate(R.layout.listview_sep, null); ((TextView) convertView.findViewById(R.id.section_title)).setText((String) obj); } return convertView; } /** * 区切り用ビュー以外のビュー作成メソッド * @param obj * @param convertView * @return objを元にカスタムしたビュー */ protected View getCustomView(Object obj, View convertView) { if (null == convertView || convertView.getId() != android.R.layout.simple_list_item_1) convertView = inflater.inflate(android.R.layout.simple_list_item_1, null); ((TextView) convertView.findViewById(android.R.id.text1)).setText((String) obj); return convertView; } @SuppressWarnings("unchecked") @Override public boolean isEnabled(int position) { int currentNumber = 0; for (Object obj : objects) { if (obj instanceof String) { if (position == currentNumber) { return false; } currentNumber++; } else { for (int i = 0; i < ((List<Object>) obj).size(); i++) { if (position == currentNumber) { return true; } currentNumber++; } } } return true; } }
解説
- コンストラクタ
- 第三引数はそのまま保持し、自身にはバラしたものをaddしておく
- getCustomView(Object obj, View convertView)
- 区切り用ビューはgetView(int position, View convertView, ViewGroup parent)の方で作成するのでここだけ実装すればOK
- isEnabled(int position)
- ビューの活性or非活性を選択できるので、区切り用フィールドの時はfalseを返す
今度は
データ追加した時のパターンとか全く考慮してないですね。また触る時間があれば大幅に書き直したいです。