代码改变世界

android中的Section ListView

2015-05-11 14:47  三戒1993  阅读(246)  评论(0编辑  收藏  举报
前几天,和ios开发的同事扯淡时发现iphone里有个section listview,分章节的列表。android中的联系人也有这种效果,首字母相同的联系人会被分在一个章节中。

后来搜了一下,android做起来也很easy。下面记录一下方便以后参考(大家改一下包名)


首先复写一下BaseAdapter:

[java] view plaincopy
  1. package com.test.activity;  
  2.   
  3. import java.util.LinkedHashMap;  
  4. import java.util.Map;  
  5. import android.content.Context;  
  6. import android.view.View;  
  7. import android.view.ViewGroup;  
  8. import android.widget.Adapter;  
  9. import android.widget.ArrayAdapter;  
  10. import android.widget.BaseAdapter;  
  11.   
  12. public class SeparatedListAdapter extends BaseAdapter {  
  13.   
  14.     public final Map<String, Adapter> sections = new LinkedHashMap<String, Adapter>();  
  15.     public final ArrayAdapter<String> headers;  
  16.     public final static int TYPE_SECTION_HEADER = 0;  
  17.   
  18.     public SeparatedListAdapter(Context context) {  
  19.         headers = new ArrayAdapter<String>(context, R.layout.list_header);  
  20.     }  
  21.   
  22.     public void addSection(String section, Adapter adapter) {  
  23.         this.headers.add(section);  
  24.         this.sections.put(section, adapter);  
  25.     }  
  26.   
  27.     public Object getItem(int position) {  
  28.         for (Object section : this.sections.keySet()) {  
  29.             Adapter adapter = sections.get(section);  
  30.             int size = adapter.getCount() + 1;  
  31.   
  32.             // check if position inside this section  
  33.             if (position == 0)  
  34.                 return section;  
  35.             if (position < size)  
  36.                 return adapter.getItem(position - 1);  
  37.   
  38.             // otherwise jump into next section  
  39.             position -= size;  
  40.         }  
  41.         return null;  
  42.     }  
  43.   
  44.     public int getCount() {  
  45.         // total together all sections, plus one for each section header  
  46.         int total = 0;  
  47.         for (Adapter adapter : this.sections.values())  
  48.             total += adapter.getCount() + 1;  
  49.         return total;  
  50.     }  
  51.   
  52.     public int getViewTypeCount() {  
  53.         // assume that headers count as one, then total all sections  
  54.         int total = 1;  
  55.         for (Adapter adapter : this.sections.values())  
  56.             total += adapter.getViewTypeCount();  
  57.         return total;  
  58.     }  
  59.   
  60.     public int getItemViewType(int position) {  
  61.         int type = 1;  
  62.         for (Object section : this.sections.keySet()) {  
  63.             Adapter adapter = sections.get(section);  
  64.             int size = adapter.getCount() + 1;  
  65.   
  66.             // check if position inside this section  
  67.             if (position == 0)  
  68.                 return TYPE_SECTION_HEADER;  
  69.             if (position < size)  
  70.                 return type + adapter.getItemViewType(position - 1);  
  71.   
  72.             // otherwise jump into next section  
  73.             position -= size;  
  74.             type += adapter.getViewTypeCount();  
  75.         }  
  76.         return -1;  
  77.     }  
  78.   
  79.     public boolean areAllItemsSelectable() {  
  80.         return false;  
  81.     }  
  82.   
  83.     public boolean isEnabled(int position) {  
  84.         return (getItemViewType(position) != TYPE_SECTION_HEADER);  
  85.     }  
  86.   
  87.     @Override  
  88.     public View getView(int position, View convertView, ViewGroup parent) {  
  89.         int sectionnum = 0;  
  90.         for (Object section : this.sections.keySet()) {  
  91.             Adapter adapter = sections.get(section);  
  92.             int size = adapter.getCount() + 1;  
  93.   
  94.             // check if position inside this section  
  95.             if (position == 0)  
  96.                 return headers.getView(sectionnum, convertView, parent);  
  97.             if (position < size)  
  98.                 return adapter.getView(position - 1, convertView, parent);  
  99.   
  100.             // otherwise jump into next section  
  101.             position -= size;  
  102.             sectionnum++;  
  103.         }  
  104.         return null;  
  105.     }  
  106.   
  107.     @Override  
  108.     public long getItemId(int position) {  
  109.         return position;  
  110.     }  
  111.   
  112. }  

然后开始写主Act,用listview适配一下上面的adapter

[java] view plaincopy
  1. package com.test.activity;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.LinkedList;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7. import android.app.Activity;  
  8. import android.os.Bundle;  
  9. import android.widget.ArrayAdapter;  
  10. import android.widget.ListView;  
  11. import android.widget.SimpleAdapter;  
  12.   
  13. public class ListSample extends Activity {  
  14.   
  15.     public final static String ITEM_TITLE = "title";  
  16.     public final static String ITEM_CAPTION = "caption";  
  17.   
  18.     public Map<String, ?> createItem(String title, String caption) {  
  19.         Map<String, String> item = new HashMap<String, String>();  
  20.         item.put(ITEM_TITLE, title);  
  21.         item.put(ITEM_CAPTION, caption);  
  22.         return item;  
  23.     }  
  24.   
  25.     @Override  
  26.     public void onCreate(Bundle icicle) {  
  27.         super.onCreate(icicle);  
  28.   
  29.         List<Map<String, ?>> security = new LinkedList<Map<String, ?>>();  
  30.         security.add(createItem("Remember passwords",  
  31.                 "Save usernames and passwords for Web sites"));  
  32.         security.add(createItem("Clear passwords",  
  33.                 "Save usernames and passwords for Web sites"));  
  34.         security.add(createItem("Show security warnings",  
  35.                 "Show warning if there is a problem with a site's security"));  
  36.   
  37.         // create our list and custom adapter  
  38.         SeparatedListAdapter adapter = new SeparatedListAdapter(this);  
  39.         adapter.addSection("Array test"new ArrayAdapter<String>(this,  
  40.                 R.layout.list_item, new String[] { "First item""Item two" }));  
  41.         adapter.addSection("Security"new SimpleAdapter(this, security,  
  42.                 R.layout.list_complex,  
  43.                 new String[] { ITEM_TITLE, ITEM_CAPTION }, new int[] {  
  44.                         R.id.list_complex_title, R.id.list_complex_caption }));  
  45.         ListView list = new ListView(this);  
  46.         list.setAdapter(adapter);  
  47.         this.setContentView(list);  
  48.     }  
  49. }  
这样java代码就写完了。。

最后把xml布局文件粘贴一下就可以跑起来了

[html] view plaincopy
  1. <!-- list_complex.xml -->    
  2. <LinearLayout    
  3.     xmlns:android="http://schemas.android.com/apk/res/android"    
  4.     android:layout_width="fill_parent"    
  5.     android:layout_height="wrap_content"    
  6.     android:orientation="vertical"    
  7.     android:paddingTop="10dip"    
  8.     android:paddingBottom="10dip"    
  9.     android:paddingLeft="15dip"    
  10.     >    
  11.     <TextView    
  12.         android:id="@+id/list_complex_title"    
  13.         android:layout_width="fill_parent"    
  14.         android:layout_height="wrap_content"    
  15.         android:textAppearance="?android:attr/textAppearanceLarge"    
  16.         />    
  17.     <TextView    
  18.         android:id="@+id/list_complex_caption"    
  19.         android:layout_width="fill_parent"    
  20.         android:layout_height="wrap_content"    
  21.         android:textAppearance="?android:attr/textAppearanceSmall"    
  22.         />    
  23. </LinearLayout>    

[html] view plaincopy
  1. <!-- list_header.xml -->    
  2. <TextView    
  3.     xmlns:android="http://schemas.android.com/apk/res/android"    
  4.     android:id="@+id/list_header_title"    
  5.     android:layout_width="fill_parent"     
  6.     android:layout_height="wrap_content"    
  7.     android:paddingTop="2dip"    
  8.     android:paddingBottom="2dip"    
  9.     android:paddingLeft="5dip"    
  10.     style="?android:attr/listSeparatorTextViewStyle" />   

[html] view plaincopy
  1. <!-- list_item.xml -->    
  2. <TextView    
  3.     xmlns:android="http://schemas.android.com/apk/res/android"    
  4.     android:id="@+id/list_item_title"    
  5.     android:layout_width="fill_parent"     
  6.     android:layout_height="fill_parent"    
  7.     android:paddingTop="10dip"    
  8.     android:paddingBottom="10dip"    
  9.     android:paddingLeft="15dip"    
  10.     android:textAppearance="?android:attr/textAppearanceLarge"    
  11.     />