Android的分类ListView

【声明】此文出自指尖飞落的博客:http://blog.csdn.net/huntersnail

——每天写一篇博客,每天做一点技术积累!


最近在项目版本迭代中需要用到分类的ListView,小区下面的N条收货地址(类似联系人)。以前都是用的很普通的ListView,都写熟透了,这种倒是没写过,就研究了下。如果是联系人那种简单的布局到也好解决,标题和子Item都可以用一个Xml布局解决。主要的难点是此次的需求是标题和子Item布局不一样,子Item还有很多点击事件需要处理,删除、编辑、选中等,有三个入口,还要根据不同的入口进行布局相应的显示。下面来说说:

思路:1、首先创建自定义适配器

   2、创建一个中间实体,用来连接Head和Body

   3、最后,在Activity里进行区分Head和Body的逻辑处理与数据装载


先贴一下项目中需要实现的效果图:

Android的分类ListView_第1张图片


1、自定义的适配器

package com.ed.categorylistview;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class CategoryAdapter extends BaseAdapter {

	private LayoutInflater inflater;
	private Context context;
	private List categoryItems;

	public CategoryAdapter(Context context, List categoryItems) {
		this.context = context;
		inflater = LayoutInflater.from(context);
		this.categoryItems = categoryItems;
	}

	@Override
	public int getCount() {
		return categoryItems.size();
	}

	@Override
	public Object getItem(int position) {
		return categoryItems.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	/**
	 * 获得视图的类型
	 */
	@Override
	public int getItemViewType(int position) {
		return ((CategoryItem) getItem(position)).type;
	}

	/**
	 * 获得视图的类型数量
	 */
	@Override
	public int getViewTypeCount() {
		return 2;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup viewGroup) {
		// 获得视图类型
		int type = getItemViewType(position);

		// 获得每一条CategoryItem
		CategoryItem item = (CategoryItem) getItem(position);

		switch (type) {
		case CategoryItem.TITLE:// Head
			if (convertView == null) {
				convertView = inflater.inflate(R.layout.item_address_title,
						null);
			}
			TextView mTitle = (TextView) convertView
					.findViewById(R.id.tv_address_title);
			// 设置Head
			mTitle.setText(item.getSection());
			break;

		case CategoryItem.ITEM:// Body
			ViewHolder viewHolder = null;
			if (convertView == null) {
				viewHolder = new ViewHolder();
				convertView = inflater.inflate(R.layout.item_address_content,
						null);
				viewHolder.mName = (TextView) convertView
						.findViewById(R.id.tv_consignee_name);
				viewHolder.mPhone = (TextView) convertView
						.findViewById(R.id.tv_consignee_phone);
				viewHolder.mAddress = (TextView) convertView
						.findViewById(R.id.tv_consignee_address);
				convertView.setTag(viewHolder);
			} else {
				viewHolder = (ViewHolder) convertView.getTag();
			}

			// 获得每一条地址信息
			AddressItem address = (AddressItem) item.getItem();
			// 进行赋值
			viewHolder.mName.setText(address.getName());
			viewHolder.mPhone.setText(address.getPhone());
			viewHolder.mAddress.setText(address.getAddress());
			break;

		}
		return convertView;
	}

	/**
	 * @ClassName ViewHolder
	 * @author Endoon
	 */
	static class ViewHolder {
		TextView mName;
		TextView mPhone;
		TextView mAddress;
	}
}


 2、创建一个中间实体,用来连接Head和Body

package com.ed.categorylistview;

public class CategoryEntity {
	public static final int TITLE=0;
	public static final int ITEM=1;
	
	public Object item;
	public int type;
	public String section;
	
	public CategoryEntity(Object item,int type,String section) {
		this.item=item;
		this.type=type;
		this.section=section;
	}
	
	public Object getItem() {
		return item;
	}
	public void setItem(Object item) {
		this.item = item;
	}
	
	public int getType() {
		return type;
	}

	public void setType(int type) {
		this.type = type;
	}

	public String getSection() {
		return section;
	}
	public void setSection(String section) {
		this.section = section;
	}
}


3、在Activity里进行区分Head和Body的逻辑处理与数据装载

package com.ed.categorylistview;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.app.Activity;
import android.widget.ListView;

/**
 * @Description 主页
 * @author Endoon
 * @date 2015-11-2 14:13:17
 */
public class MainActivity extends Activity {
	private ListView mListView;
	private CategoryAdapter mAdapter;
	private List categoryItems = new ArrayList();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mListView = (ListView) findViewById(R.id.lv_content);
		initView();
	}

	/**
	 * 初始化视图
	 */
	private void initView() {
		initCategoryItems(simulateData());
		mAdapter = new CategoryAdapter(MainActivity.this, categoryItems);
		mListView.setAdapter(mAdapter);

	}

	/**
	 * 区分Head(头)和Body(体)的逻辑处理:此方法非常关键
	 * @param simulateData 模拟的数据源
	 */
	private void initCategoryItems(List
simulateData) { categoryItems.clear(); for (int i = 0; i < simulateData.size(); i++) { Address address = simulateData.get(i); // 当前的Head String currentTitle = address.getTitle(); // 判断上一个Head:判断是否有上一个Head,如有有则用上一个Head,如果没有则用空表示; String lastTitle = (i - 1) >= 0 ? (simulateData.get(i - 1).getTitle()) : " "; /** * 通过对当前Head与上一个Head进行对比,如果不是同一个头,则添加进行存储 */ if (!currentTitle.equals(lastTitle)) { CategoryEntity firstItem=new CategoryEntity(null, CategoryEntity.TITLE, currentTitle); categoryItems.add(firstItem); } /** * 循环添加Head下面Body,添加完当前Head的Body则会进行下一轮的Head对比,不相等则再进行新的一轮的Body的添加。以此类推 */ List items=address.getItems(); for (AddressItem addressItem : items) { CategoryEntity item=new CategoryEntity(addressItem, CategoryEntity.ITEM, currentTitle); categoryItems.add(item); } } } /** * 模拟数据源 * @return 数据源 */ private List
simulateData() { List
list = new ArrayList
(); for (int i = 0; i < 3; i++) { Address address = new Address(); address.setTitle("碧桂园威尼斯城" + i + 1 + "期"); List listAdrs = new ArrayList(); for (int j = 0; j < 3; j++) { AddressItem item = new AddressItem(); item.setName("老王" + j); item.setPhone("1551111111" + j); item.setAddress("北京市朝阳区长安街第" + j + "号"); listAdrs.add(item); } address.setItems(listAdrs); list.add(address); } return list; } }

4、Demo实现的效果图

Android的分类ListView_第2张图片


5、源码下载地址


☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆转载请注明出处☞指尖飞落的博客☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆



你可能感兴趣的:(☞Android布局☞)