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


    之前的文章  《 Android ListView分类/分组效果 - 第一种实现方式》,当前是第二种实现方式。


一、实现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创建的视图类型的数量


2. 视图 -- 在Adapter.getView中通过getItemViewType获取item类型,当前实现为分类item与普通item两种,根据类型创建不同的VIew对象

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 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 getData() {
		ArrayList listData = new ArrayList();
        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 mListData;
	private LayoutInflater mInflater;
	
	
	public CategoryAdapter(Context context, ArrayList 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 mCategoryItem = new ArrayList();

	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




你可能感兴趣的:(Android,UI)