您的位置:首页 > 移动开发 > Android开发

Android ListView分类/分组效果 - 第二种实现方式

2015-12-24 18:35 459 查看
http://blog.csdn.net/androiddevelop/article/details/8316759

一、实现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;

}

}

三、源码下载地址

2013-03-31 更新与第一种方式关联

转载请注明出处:http://blog.csdn.net/love_world_/article/details/8316759
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: