自定义控件之CascadeLayout(二)

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


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的小修改
@Override
protected 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值