Android ListView 分组基础adapter

本文介绍了一种用于Android应用开发中ListView组件的分组显示解决方案。通过自定义ListAdapter,实现了复杂的数据分组及头部、尾部视图的支持。文章详细解释了类GroupAdapter的实现原理,并提供了一个具体的使用案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

</pre><pre name="code" class="java">import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public abstract class ListGroupAdapter extends BaseAdapter {
	
	
 	public Context mContext;
	
	
	
	public int getSection(){//获取切片
		return 1;
	}
	
	/**
	 * 根据切片section 获取对应的 row item
	 * @param section
	 * @return
	 */
	public abstract int getRow(int section);

	@Override
	final public int getCount() {
		int section = getSection();
		int count = 0;
		for (int i = 0; i < section; i++) {
			int header = isGroupHeaderForSection(i)?1:0;
			int footer = isGroupFooterForSection(i)?1:0;
			count = count + getRow(i) + header + footer;
		}
		return count;
	}

	
	@Override
	final public int getItemViewType(int position) {
		 IndexPath indexPath = findIndexPathForPosition(position);
		 if (isGroupHeaderForSection(indexPath.section) && indexPath.row == 0 ) {//有头
			 return getItemHeaderViewType(indexPath);
		 }
		 
		 if (isGroupFooterForSection(indexPath.section)) {//有尾
			 int row = getRow(indexPath.section);
			 int header = isGroupHeaderForSection(indexPath.section)?1:0;
			 if (row == indexPath.row - header) {//到尾部了
				return getItemFooterViewType(indexPath);
			}
		 }
		 return getItemViewType(indexPath);
	}

	
	/**
	 * 获取 view type的总数
	 */
	@Override
	public int getViewTypeCount() {
		return 3;
	}
	
	/**
	 * 
	 * @param indexPath 改位置的 view type
	 * @return
	 */
	public int getItemViewType(IndexPath indexPath){
		return 0;
	}
	
	/**
	 * 
	 * @param indexPath section Footer 位置的 view type
	 * @return
	 */
	public int getItemFooterViewType(IndexPath indexPath){
		return 1;
	}
	/**
	 * 
	 * @param indexPath  section Header position view type
	 * @return
	 */
	public int getItemHeaderViewType(IndexPath indexPath){
		return 2;
	}
	
	
	/**
	 * 根据 postion 计算 indexPath
	 * @param position
	 * @return
	 */
	final public IndexPath findIndexPathForPosition(int position){
		position -= getListHeadCount();
		int section = getSection();
		int count = 0;
		int sec = 0;
		for (int i = 0; i < section; i++) {
			int header = isGroupHeaderForSection(i)?1:0;
			int footer = isGroupFooterForSection(i)?1:0;
			
			count = count + getRow(i) + header + footer;
			if (count > position) {
				sec = i;
				count = count - getRow(i) - header - footer;
				break;
			}
		}
		
		IndexPath indexPath = new IndexPath();
		indexPath.section = sec;
		indexPath.row = position-count;
		
		Log.d("demo", "" +indexPath +" po: "+ position +" getRow:"+getRow(indexPath.section));
		
		return indexPath;
	}
	
	/**
	 * listview  header 的数量决定 position 的位置
	 * @return
	 */
	public int getListHeadCount(){
		return 0;
	}
	

	/**
	 * 次getview 不能被重写 
	 */
	@Override
	final public View getView(int position, View convertView, ViewGroup parent) {
		
		 IndexPath indexPath = findIndexPathForPosition(position);
		 
		 int header = isGroupHeaderForSection(indexPath.section)?1:0;
		 
		 if (isGroupHeaderForSection(indexPath.section) && indexPath.row == 0) {//有头
			 return getHeaderView(position, indexPath.section, convertView, parent);
		 }
		 
		 if (isGroupFooterForSection(indexPath.section)) {//有尾
			 int row = getRow(indexPath.section);
			 if (row == indexPath.row - header) {//到尾部了
				return getFooterView(position, indexPath.section, convertView, parent);
			}
		 }
		 
		 if (isGroupHeaderForSection(indexPath.section)) {//包含header row位置 -1 和 list index 保持一致
			 indexPath.row -= 1;
		 }
		 
		 //内容item
		 return getView(position, indexPath, convertView, parent);
		
	}


	
	/**
	 * 该组是否包含HeadView
	 * @param section
	 * @return
	 */
	public boolean isGroupHeaderForSection(int section){
		return false;
	}
	/**
	 * 该组是否包含FooterVew
	 * @param section
	 * @return
	 */
	public boolean isGroupFooterForSection(int section){
		return false;
	}
	
	/**
	 * body item的 view 
	 * @param position
	 * @param indexPath
	 * @param convertView
	 * @param parent
	 * @return
	 */
	public abstract View getView(int position,IndexPath indexPath,View convertView,ViewGroup parent);
	
	public View getHeaderView(int position,int section,View convertView,ViewGroup parent){
		if (isGroupHeaderForSection(section)) {
			TextView header = null;
			if (convertView!=null) {
				header =(TextView) convertView;
			}else {
				header = new TextView(mContext);
			}
			header.setText("第:"+section+" header");
			return header;
		}
		return null;
	}
	public View getFooterView(int position,int section,View convertView,ViewGroup parent){
		if (isGroupFooterForSection(section)) {
			TextView footer =null;
			if (convertView != null) {
				footer = (TextView) convertView;
			}else {
				footer = new TextView(mContext);	
			}
			footer.setText("第:"+section +" footer");
			return footer;
		}
		return null;
	}
	
	
	public static class IndexPath{
		public int row;
		public int section;
		
		@Override
		public String toString() {
			return "IndexPath [row=" + row + ", section=" + section + "]";
		}
		
		
		
	}
	
}
</pre><pre name="code" class="java">使用:
<pre name="code" class="java">public class DemoAdapter  extends ListGroupAdapter implements OnClickListener{

	public List<OrderBean> orderBeans;
	
	LayoutInflater mInflater;
	
	public DemoAdapter( List<OrderBean> orderBeans, Context context ){
		mContext = context;
		mInflater = LayoutInflater.from(context);
		
		this.orderBeans = orderBeans;
		
	}
	
	@Override
	public Object getItem(int position) {
		return null;
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int getSection() {
		return orderBeans.size();
	}
	
	@Override
	public int getRow(int section) {
		OrderBean bean = orderBeans.get(section);
		if (bean.isShowAll) {
			return bean.goodsBeans.size();
		}else {
			return bean.goodsBeans.size()>2?2:bean.goodsBeans.size();
		}
	}

	@Override
	public View getView(int position, IndexPath indexPath, View convertView,
			ViewGroup parent) {
		View view = null;
		if (convertView!=null) {
			view = convertView;
		}else{
			view = mInflater.inflate(R.layout.goods_item_layout, null);
		}
		TextView goodsView = (TextView) view.findViewById(R.id.goods_name);
		goodsView.setText(orderBeans.get(indexPath.section).goodsBeans.get(indexPath.row).goodsName);
		return view;
	}

	@Override
	public boolean isGroupHeaderForSection(int section) {
//		if (section%2==0) {
//			return false;
//		}
		return true;
	}
	@Override
	public boolean isGroupFooterForSection(int section) {
		if (orderBeans.get(section).goodsBeans.size()<=2) {
			return false ;
		}
		return true;
	}
	@Override
	public View getFooterView(int position, int section, View conView,
			ViewGroup parent) {
		View view = null;
		if (conView!=null) {
			view = conView ;
		}else{
			view = mInflater.inflate(R.layout.footer_item_layout, null);
		}
		
		Button button = (Button) view.findViewById(R.id.button1);
		button.setTag(section);
		OrderBean bean = orderBeans.get(section);
		if (bean.isShowAll) {
			button.setText("关闭 - " + bean.goodsBeans.size());	
		}else {
			button.setText("打开 - "+bean.goodsBeans.size());
		}
		
		button.setOnClickListener(this);
		
		return view;
	}

	@Override
	public void onClick(View v) {
		
		switch (v.getId()) {
		case R.id.button1:
			int section = (Integer) v.getTag();
			OrderBean bean = orderBeans.get(section);
			bean.isShowAll = !bean.isShowAll;
			notifyDataSetChanged();
			break;
		default:
			break;
		}
	}
}




                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值