http://blog.csdn.net/androiddevelop/article/details/8316759
一、实现ListView分类显示效果,目前我知道的有两种方案:
1. 每一个ItemView都包含用于显示分类信息的view(TitleView)和用于显示内容view。之前实现文章
2. 通过ListView加载不同类型的Item实现。本文属于这种实现方式
二 当前实现描述:
1. 与自定义Adapter的ListVIew雷同,只是多使用两个BaseAdapter API:
- 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创建的视图类型的数量
3. 数据 -- 分类的数据通过List包含自定义数据对象Category,Category内部包含List用于存储当前Category item数据。
4. 覆写BaseAdapter.areAllItemsEnabled 和 BaseAdapter.isEnabled两个方法,确保分类Item不可点击
三 效果图
四 源码下载与伪码
* Activity
- 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
- 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;
- }
- }
* 数据对象
- 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;
- }
- }
三、源码下载地址
2013-03-31 更新与第一种方式关联
转载请注明出处:http://blog.csdn.net/love_world_/article/details/8316759