首页 > 代码库 > 自定义ViewGroup

自定义ViewGroup

先来个效果图


先给我们的自定义ViewGroup定制两个属性
attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 给我们的viewgroup定义专属的自己的属性  并且指定类型 -->
    <declare-styleable name="custom_view_group">
        <attr name="horizontal_spacing" format="dimension" />
        <attr name="vertical_spacing" format="dimension" />
    </declare-styleable>

</resources>



给自定义的属性来个默认值
dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <dimen name="horizontal_spacing">10dp</dimen>
    <dimen name="vertical_spacing">10dp</dimen>

</resources>




自定义的ViewGroup的具体代码

CustomViewGroup.java
package com.yufeng.androidtest;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

public class CustomViewGroup extends ViewGroup {
	private int mHorizontalSpacing;
	private int mVerticalSpacing;
	private CustomLayoutParams[] point;

	public CustomViewGroup(Context context, AttributeSet attrs) {
		super(context, attrs);
		initCustomViewGroup(context, attrs);
	}

	private void initCustomViewGroup(Context context, AttributeSet attrs) {
		TypedArray typedArray = context.obtainStyledAttributes(attrs,
				R.styleable.custom_view_group);
		// 获取默认的间距并赋值给定制的属性
		mHorizontalSpacing = typedArray.getDimensionPixelSize(
				R.styleable.custom_view_group_horizontal_spacing,
				getResources()
						.getDimensionPixelSize(R.dimen.horizontal_spacing));
		mVerticalSpacing = typedArray.getDimensionPixelSize(
				R.styleable.custom_view_group_vertical_spacing, getResources()
						.getDimensionPixelSize(R.dimen.vertical_spacing));
		// 释放
		typedArray.recycle();
	}

	public CustomViewGroup(Context context) {
		super(context);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		// 存放每个控件的点用自己写的CustomLayoutParams
		// 用于子控件的x和y轴位置以及本控件的最终大小
		int width = 0;
		int height = 0;
		// 获取本控件下子控件的个数
		final int count = getChildCount();
		point = new CustomLayoutParams[count];
		for (int i = 0; i < count; i++) {
			// 获取子控件
			View child = getChildAt(i);
			// 测量子控件的长度让子控件去搞吧,反正系统写好了,如果子控件还有子控件他也会才处理的
			measureChild(child, widthMeasureSpec, heightMeasureSpec);
			// 计算好我们给设定的子控件位置 定制自己的控件
			width = getPaddingLeft() + mHorizontalSpacing * i;
			height = getPaddingTop() + mVerticalSpacing * i;

			// 保存到子控件的点到CustomLayoutParams中
			CustomLayoutParams customLayoutParams = new CustomLayoutParams();
			customLayoutParams.x = width;
			customLayoutParams.y = height;
			point[i] = customLayoutParams;
		}

		width += getPaddingRight() + getChildAt(count - 1).getMeasuredWidth();
		height += getPaddingBottom()
				+ getChildAt(count - 1).getMeasuredHeight();
		// 必须调用计算自己的大小
		setMeasuredDimension(resolveSize(width, widthMeasureSpec),
				resolveSize(height, heightMeasureSpec));
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		// 把他和控件都画出来
		final int count = getChildCount();
		for (int i = 0; i < count; i++) {
			// 获取子控件
			View view = getChildAt(i);
			// 画控件,就是从那画到那
			view.layout(point[i].x, point[i].y,
					point[i].x + view.getMeasuredWidth(),
					point[i].y + view.getMeasuredHeight());
		}
	}

	class CustomLayoutParams {
		// 用作保存点
		int x;
		int y;
	}
	
	
}




布局文件
custom_view_group.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:cascade="http://schemas.android.com/apk/res/com.yufeng.androidtest"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
  <!--xmlns:cascade 使用自定义的属性必须声明引用  只需要把后半部分改成你的包名即可 -->
    <com.yufeng.androidtest.CustomViewGroup
        android:id="@+id/customViewGroup1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        cascade:horizontal_spacing="10dp"
        cascade:vertical_spacing="10dp" >
        <View 
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="#FF0000"
            />
         <View 
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="#00FF00"
            />
          <View 
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="#0000FF"
            />
    </com.yufeng.androidtest.CustomViewGroup>

</LinearLayout>