1. 程式人生 > >Android的分類ListView

Android的分類ListView

【宣告】此文出自指尖飛落的部落格:http://blog.csdn.net/huntersnail

——每天寫一篇部落格,每天做一點技術積累!

最近在專案版本迭代中需要用到分類的ListView,小區下面的N條收貨地址(類似聯絡人)。以前都是用的很普通的ListView,都寫熟透了,這種倒是沒寫過,就研究了下。如果是聯絡人那種簡單的佈局到也好解決,標題和子Item都可以用一個Xml佈局解決。主要的難點是此次的需求是標題和子Item佈局不一樣,子Item還有很多點選事件需要處理,刪除、編輯、選中等,有三個入口,還要根據不同的入口進行佈局相應的顯示。下面來說說:

思路:1、首先建立自定義介面卡

   2、建立一箇中間實體,用來連線Head和Body

   3、最後,在Activity裡進行區分Head和Body的邏輯處理與資料裝載

先貼一下專案中需要實現的效果圖:


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<CategoryItem> categoryItems;

	public CategoryAdapter(Context context, List<CategoryItem> 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<CategoryEntity> categoryItems = new ArrayList<CategoryEntity>();

	@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<Address> 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<AddressItem> items=address.getItems();
			for (AddressItem addressItem : items) {
				CategoryEntity item=new CategoryEntity(addressItem, CategoryEntity.ITEM, currentTitle);
				categoryItems.add(item);
			}
		}
	}

	/**
	 * 模擬資料來源
	 * @return 資料來源
	 */
	private List<Address> simulateData() {
		List<Address> list = new ArrayList<Address>();
		for (int i = 0; i < 3; i++) {
			Address address = new Address();
			address.setTitle("碧桂園威尼斯城" + i + 1 + "期");

			List<AddressItem> listAdrs = new ArrayList<AddressItem>();
			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實現的效果圖


☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆轉載請註明出處☞指尖飛落的部落格☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆