AndroidのListViewには、iPhoneのUITableViewのsectionのような概念がありません。
これをAndroidのListViewで実現するためのコンポーネントを簡単に作って見ました。
public class MultiSectionAdapter extends BaseAdapter { /** セルがセクションヘッダーであることを表す値 */ public final static int TYPE_SECTION_HEADER = 0; /** 各セクションのValue部を保持するアダプターの集合 */ public final Mapsections = new LinkedHashMap (); /** セクションヘッダーアダプター */ public final ArrayAdapter headers; public final Context context; public MultiSectionAdapter(Context context) { super(); this.context = context; headers = new ArrayAdapter (context, R.layout.list_section_header); } @Override public int getCount() { // ヘッダーを除いて、セルの数を返す int total = 0; for(Adapter adapter : this.sections.values()) { if (adapter == null) { continue; } total += adapter.getCount() + 1; } return total; } @Override public Object getItem(int position) { for(Object section : this.sections.keySet()) { Adapter adapter = sections.get(section); int size = adapter.getCount() + 1; if(position == 0) return section; if(position < size) return adapter.getItem(position - 1); position -= size; } return null; } @Override public long getItemId(int position) { return position; } @Override public int getViewTypeCount() { int total = 1; for(Adapter adapter : this.sections.values()) { if (adapter == null) { continue; } total += adapter.getViewTypeCount(); } return total; } @Override public int getItemViewType(int position) { int type = 1; for(Object section : this.sections.keySet()) { Adapter adapter = sections.get(section); int size = adapter.getCount() + 1; if(position == 0) return TYPE_SECTION_HEADER; if(position < size) return type + adapter.getItemViewType(position - 1); position -= size; type += adapter.getViewTypeCount(); } return -1; } @Override public boolean isEnabled(int position) { return (getItemViewType(position) != TYPE_SECTION_HEADER); } @Override public View getView(int position, View convertView, ViewGroup parent) { int sectionNum = 0; for(Object section : this.sections.keySet()) { Adapter adapter = sections.get(section); int size = adapter.getCount() + 1; if(position == 0) return headers.getView(sectionNum, null, parent); if(position < size) return adapter.getView(position - 1, convertView, parent); position -= size; sectionNum++; } return null; } /** * セクションヘッダーと対となるアダプターをセットする * * @param section セクションヘッダー * @param adapter セクションアダプター */ public void addSection(String section, Adapter adapter) { this.headers.add(section); this.sections.put(section, adapter); } }
そして色々と端折ってますが、このAdapterは以下のように利用します。
public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ListView list = (ListView) findViewById(R.id.listView); // MultiSectionAdapterに追加するセクション その1 @SuppressWarnings("serial") Listnames1 = new ArrayList (){{add("相田"); add("石田"); add("上田");}}; ArrayAdapter adapter1 = new ArrayAdapter (this, android.R.layout.simple_list_item_1, names1); // MultiSectionAdapterに追加するセクション その2 @SuppressWarnings("serial") List names2 = new ArrayList (){{add("加藤"); add("木村"); add("久保");}}; ArrayAdapter adapter2 = new ArrayAdapter (this, android.R.layout.simple_list_item_1, names2); // ヘッダー部のラベルと、対応するAdapterを渡す UserAdapter adapter = new UserAdapter(this); adapter.addSection("ア行", adapter1); adapter.addSection("カ行", adapter2); list.setAdapter(adapter); } } class UserAdapter extends MultiSectionAdapter { public UserAdapter(Context context) { super(context); } }
- ヘッダー部に任意のViewを指定できない
- UITableViewと比較して、footer部がない
などなど、幾つかの不足・問題点はあるのですが、
現実の要件としてはこれで十分事足りるのではないかと思います。
0 件のコメント:
コメントを投稿