自定义控件之CascadeLayout(二)

来源:互联网 发布:刘若英我知谁掌管明天 编辑:程序博客网 时间:2024/05/22 16:40

需求是:进一步学习自定义控件,为子视图添加自定义属性


1. 在attr中添加自定义属性
<declare-styleable name= "CascadeLayout_LayoutParams">    <attr name ="layout_vertical_spacing" format= "dimension" /></declare-styleable>

这里的属性名是layout_vertical_spacing,因为该属性名前缀是layout_,同时又不是view的固有属性,所以该属性会被添加到layoutparams的属性表中。

2. 在自定义的layoutparams中获取该属性
public static class LayoutParams extends ViewGroup.LayoutParams {     int x;     int y;     int verticalSpacing;     public LayoutParams(Context context, AttributeSet attrs) {            super(context, attrs);           TypedArray a = context.obtainStyledAttributes(attrs,                     R.styleable. CascadeLayout_LayoutParams);            try {                 verticalSpacing = a                           .getDimensionPixelSize(                                     R.styleable. CascadeLayout_LayoutParams_layout_vertical_spacing ,                                     -1);           } finally {                a.recycle();           }     }     public LayoutParams( int w, int h) {            super(w, h);     }}


3. 在view的布局文件中,添加该属性

<qingfengmy.cascadelayout.CascadeLayout    android:layout_width= "match_parent"    android:layout_height= "match_parent"    cascade:horizontal_spacing= "30dp"    cascade:vertical_spacing= "20dp" >    <View        android:layout_width= "100dp"        android:layout_height= "150dp"        cascade:layout_vertical_spacing="90dp"  这里添加了子视图的属性        android:background= "#FF0000" />    <View        android:layout_width= "100dp"        android:layout_height= "150dp"        android:background= "#00FF00" />    <View        android:layout_width= "100dp"        android:layout_height= "150dp"        android:background= "#0000FF" /></qingfengmy.cascadelayout.CascadeLayout>

4. onmeasure的小修改
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {     int width = 0;     int height = getPaddingTop();     int verticalSpacing;      int count = getChildCount();     for (int i = 0; i < count; i++) {           verticalSpacing = mVerticalSpacing;            View child = getChildAt(i);            // 令每个子view测量自身           measureChild(child, widthMeasureSpec, heightMeasureSpec);           LayoutParams lp = (LayoutParams) child.getLayoutParams();           width = getPaddingLeft() + mHorizontalSpacing * i;            // layoutParams中保存每个子视图左上角的x和y坐标           lp. x = width;           lp. y = height;            if (lp. verticalSpacing >= 0) {                verticalSpacing = lp. verticalSpacing;           }           width += child.getMeasuredWidth();           height += verticalSpacing;     }     // 使用计算所得的宽高设置整个布局的测量尺寸     width += getPaddingRight();     height += getChildAt(getChildCount() - 1).getMeasuredHeight()                + getPaddingBottom();     // resolveSize的主要作用就是根据你提供的大小和MeasureSpec,返回你想要的大小值,这个里面根据传入模式的不同来做相应的处理     setMeasuredDimension(resolveSize(width, widthMeasureSpec),                 resolveSize(height, heightMeasureSpec));}

5.源码
https://github.com/qingfengmy/Cascadelayout



0 0
原创粉丝点击