Android的分類ListView
阿新 • • 發佈:2019-02-05
【宣告】此文出自指尖飛落的部落格: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
3、在Activity裡進行區分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; } }
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實現的效果圖
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆轉載請註明出處☞指尖飛落的部落格☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆