之前的文章 《 Android ListView分类/分组效果 - 第一种实现方式》,当前是第二种实现方式。
一、实现ListView分类显示效果,目前我知道的有两种方案:
1. 每一个ItemView都包含用于显示分类信息的view(TitleView)和用于显示内容view。之前实现文章
2. 通过ListView加载不同类型的Item实现。本文属于这种实现方式
二 当前实现描述:
1. 与自定义Adapter的ListVIew雷同,只是多使用两个BaseAdapter API:
[java] view plaincopyprint? public int getItemViewType (int position) 获取通过getView为指定项目创建的视图的类型。 参数 position 在adapter数据里我们想知道视图类型的项目的位置 返回值 一个整形的视图类型的描述。如果一个视图通过getView(int, View, ViewGroup)方法转换成另一个视图,则两个视图将共享同一类型。注意:整形必须在0和getViewTypeCount()– 1之间。IGNORE_ITEM_VIEW_TYPE也可以返回。 public int getViewTypeCount () 返回通过getView(int, View, ViewGroup))创建的视图的类型数量。每一个类型表示一组通过getView(int, View, ViewGroup)方法转换过的视图。如果adapter针对所有项目返回相同的视图类型,这个方法返回1。这个方法仅仅当adapter设置在AdapterView时调用。 返回值 通过这个adapter创建的视图类型的数量
2. 视图 -- 在Adapter.getView中通过getItemViewType获取item类型,当前实现为分类item与普通item两种,根据类型创建不同的VIew对象
3. 数据 -- 分类的数据通过List包含自定义数据对象Category,Category内部包含List用于存储当前Category item数据。
4. 覆写BaseAdapter.areAllItemsEnabled 和 BaseAdapter.isEnabled两个方法,确保分类Item不可点击
源码下载与伪码
* Activity
[java] view plaincopyprint? public class MainActivity extends Activity { private CategoryAdapter mCustomBaseAdapter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ListView listView = (ListView) findViewById(R.id.listView1); // 数据 ArrayList<Category> listData = getData(); mCustomBaseAdapter = new CategoryAdapter(getBaseContext(), listData); // 适配器与ListView绑定 listView.setAdapter(mCustomBaseAdapter); listView.setOnItemClickListener(new ItemClickListener()); } private class ItemClickListener implements OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(getBaseContext(), (String)mCustomBaseAdapter.getItem(position), Toast.LENGTH_SHORT).show(); } } /** * 创建测试数据 */ private ArrayList<Category> getData() { ArrayList<Category> listData = new ArrayList<Category>(); Category categoryOne = new Category("路人甲"); categoryOne.addItem("马三立"); categoryOne.addItem("赵本山"); categoryOne.addItem("郭德纲"); categoryOne.addItem("周立波"); Category categoryTwo = new Category("事件乙"); categoryTwo.addItem("**贪污"); categoryTwo.addItem("**照门"); Category categoryThree = new Category("书籍丙"); categoryThree.addItem("10天学会***"); categoryThree.addItem("**大全"); categoryThree.addItem("**秘籍"); categoryThree.addItem("**宝典"); categoryThree.addItem("10天学会***"); categoryThree.addItem("10天学会***"); categoryThree.addItem("10天学会***"); categoryThree.addItem("10天学会***"); Category categoryFour = new Category("书籍丙"); categoryFour.addItem("河南"); categoryFour.addItem("天津"); categoryFour.addItem("北京"); categoryFour.addItem("上海"); categoryFour.addItem("广州"); categoryFour.addItem("湖北"); categoryFour.addItem("重庆"); categoryFour.addItem("山东"); categoryFour.addItem("陕西"); listData.add(categoryOne); listData.add(categoryTwo); listData.add(categoryThree); listData.add(categoryFour); return listData; } }
* Adapter
[java] view plaincopyprint? public class CategoryAdapter extends BaseAdapter { private static final int TYPE_CATEGORY_ITEM = 0; private static final int TYPE_ITEM = 1; private ArrayList<Category> mListData; private LayoutInflater mInflater; public CategoryAdapter(Context context, ArrayList<Category> pData) { mListData = pData; mInflater = LayoutInflater.from(context); } @Override public int getCount() { int count = 0; if (null != mListData) { // 所有分类中item的总和是ListVIew Item的总个数 for (Category category : mListData) { count += category.getItemCount(); } } return count; } @Override public Object getItem(int position) { // 异常情况处理 if (null == mListData || position < 0|| position > getCount()) { return null; } // 同一分类内,第一个元素的索引值 int categroyFirstIndex = 0; for (Category category : mListData) { int size = category.getItemCount(); // 在当前分类中的索引值 int categoryIndex = position - categroyFirstIndex; // item在当前分类内 if (categoryIndex < size) { return category.getItem( categoryIndex ); } // 索引移动到当前分类结尾,即下一个分类第一个元素索引 categroyFirstIndex += size; } return null; } @Override public int getItemViewType(int position) { // 异常情况处理 if (null == mListData || position < 0|| position > getCount()) { return TYPE_ITEM; } int categroyFirstIndex = 0; for (Category category : mListData) { int size = category.getItemCount(); // 在当前分类中的索引值 int categoryIndex = position - categroyFirstIndex; if (categoryIndex == 0) { return TYPE_CATEGORY_ITEM; } categroyFirstIndex += size; } return TYPE_ITEM; } @Override public int getViewTypeCount() { return 2; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { int itemViewType = getItemViewType(position); switch (itemViewType) { case TYPE_CATEGORY_ITEM: if (null == convertView) { convertView = mInflater.inflate(R.layout.listview_item_header, null); } TextView textView = (TextView) convertView.findViewById(R.id.header); String itemValue = (String) getItem(position); textView.setText( itemValue ); break; case TYPE_ITEM: ViewHolder viewHolder = null; if (null == convertView) { convertView = mInflater.inflate(R.layout.listview_item, null); viewHolder = new ViewHolder(); viewHolder.content = (TextView) convertView.findViewById(R.id.content); viewHolder.contentIcon = (ImageView) convertView.findViewById(R.id.content_icon); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } // 绑定数据 viewHolder.content.setText( (String)getItem(position) ); viewHolder.contentIcon.setImageResource(R.drawable.ic_launcher); break; } return convertView; } @Override public boolean areAllItemsEnabled() { return false; } @Override public boolean isEnabled(int position) { return getItemViewType(position) != TYPE_CATEGORY_ITEM; } private class ViewHolder { TextView content; ImageView contentIcon; } }
* 数据对象
[java] view plaincopyprint? public class Category { private String mCategoryName; private List<String> mCategoryItem = new ArrayList<String>(); public Category(String mCategroyName) { mCategoryName = mCategroyName; } public String getmCategoryName() { return mCategoryName; } public void addItem(String pItemName) { mCategoryItem.add(pItemName); } /** * 获取Item内容 * * @param pPosition * @return */ public String getItem(int pPosition) { // Category排在第一位 if (pPosition == 0) { return mCategoryName; } else { return mCategoryItem.get(pPosition - 1); } } /** * 当前类别Item总数。Category也需要占用一个Item * @return */ public int getItemCount() { return mCategoryItem.size() + 1; } }
源码下载地址:http://download.csdn.net/detail/love_world_/4904015
转:http://blog.csdn.net/androiddevelop/article/details/8316759