天天记录 - 自定义ViewGroup使用Adapter提供视图

本文介绍如何自定义一个ViewGroup,并利用Adapter来提供视图内容。首先,你需要继承ViewGroup并覆盖onMeasure和onLayout方法。然后,在Activity中创建视图,设置数据和Adapter。虽然功能已达成,但作者认为onMeasure和onLayout的实现仍有优化空间。

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


例子下载地址


1. 创建ViewGroup继承自ViewGroup,覆写onMeasure和onLayout

public class CustomViewGroup extends ViewGroup {

	// ===========================================================
	// Fields
	// ===========================================================

	private BaseAdapter mAdapter;
	
	// ===========================================================
	// Constructors
	// ===========================================================

	public CustomViewGroup(Context context) {
		super(context);
	}
	
	public CustomViewGroup(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	
	public CustomViewGroup(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}
	
	// ===========================================================
	// Getter & Setter
	// ===========================================================

	public void setAdapter(BaseAdapter pAdapter) {
		mAdapter = pAdapter;
	}
	
	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int width = MeasureSpec.getSize(widthMeasureSpec);
		int height = MeasureSpec.getSize(heightMeasureSpec);

		// 从Adapter获取所有的child View
		int count = mAdapter.getCount();
		for (int i = 0; i < count; i++) {
			View view = mAdapter.getView(i, null, null);
			
			// 添加到ViewGroup
			addView(view);
			
			int measuredWidth = view.getMeasuredWidth();
			int measuredHeight = view.getMeasuredHeight();
			
			view.measure(measuredWidth, measuredHeight);
		}
		
		setMeasuredDimension(width, height);
	}
	
	@Override
	protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
		
		if (changed == false) {
			return;
		}
		
		// 用于纵向显示
		// 累加每个视图的高度,便于下一个视图获取top顶点值
		int totalHeight = 0;
		
		int childCount = getChildCount();
		for (int i = 0; i < childCount; i++) {
			
			View childView = getChildAt(i);
			
			int measuredHeight = childView.getMeasuredHeight();
			int measuredWidth = childView.getMeasuredWidth();
			
			// 设置每个View的显示位置
			childView.layout(left, totalHeight, measuredWidth, totalHeight + measuredHeight);
			
			totalHeight += measuredHeight;
		}
		
	}

}


2. 在Activity创建视图,数据,Adapter

public class CustomViewGroup_AdapterActivity extends Activity {

	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // 创建视图
        CustomViewGroup customViewGroup = new CustomViewGroup(this);
        customViewGroup.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
        
        // Activity绑定View
        setContentView(customViewGroup);
        
        // 创建数据
        ArrayList<TextViewInfo> arrayList = new ArrayList<TextViewInfo>();
        arrayList.add(new TextViewInfo("自定义", Color.BLUE));
        arrayList.add(new TextViewInfo("ViewGroup", Color.YELLOW));
        arrayList.add(new TextViewInfo("Adapter", Color.RED));
        
        // 创建Adapter
        CustomAdapter customAdapter = new CustomAdapter(this, arrayList);
        
        customViewGroup.setAdapter(customAdapter);
        
        
    }
	
	
	
	
	
	
	/**
	 *	存放TextView的文本和背景颜色实体
	 */
	public class TextViewInfo {
		
		private int mColor;
		private String mName;
		
		public TextViewInfo(String pName, int pColor) {
			mName = pName;
			mColor = pColor;
		}

		public int getColor() {
			return mColor;
		}

		public void setColor(int mColor) {
			this.mColor = mColor;
		}

		public String getName() {
			return mName;
		}

		public void setName(String mName) {
			this.mName = mName;
		}
		
	}
	
	
	
	
}


效果图:



扩展:

查看下ListView源码

此例子虽然实现了期望的功能,总感觉onMeasure和onLayout还有更好的做法






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值