Android--View自定义—标签<流式布局>

一:效果描述:
1-:可以显示标签,横向排列;
2-:可自动换行;

二:需要分析:
1-:需要自定义继承自ViewGroup;
2-:继承自ViewGroup时,需要处理子View的宽高设置以及padding等;
3-:重写onMeasure(),onLayout();

三:功能实现思路:
1-:测量布局的宽高;
2-:布局变化控制;

四:功能实现:
1-:

public class MyFlowLayout extends ViewGroup {

private int  verticalSpacing = 20;
public MyFlowLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

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

    int paddingLeft = getPaddingLeft();
    int paddingRight = getPaddingRight();
    int paddingTop = getPaddingTop();
    int paddingBottom = getPaddingBottom();

    int widthUsed = paddingLeft + paddingRight;
    int heightUsed = paddingTop + paddingBottom;

    int childMaxHeightOfThisLine = 0;
    int childCount = getChildCount();
    for (int i = 0; i < childCount; i++) {
        View child = getChildAt(i);
        if (child.getVisibility() != GONE) {
            int childUsedWidth = 0;
            int childUsedHeight = 0;
            measureChild(child,widthMeasureSpec,heightMeasureSpec);
            childUsedWidth += child.getMeasuredWidth();
            childUsedHeight += child.getMeasuredHeight();

            LayoutParams childLayoutParams = child.getLayoutParams();

            MarginLayoutParams marginLayoutParams = (MarginLayoutParams) childLayoutParams;

            childUsedWidth += marginLayoutParams.leftMargin + marginLayoutParams.rightMargin;
            childUsedHeight += marginLayoutParams.topMargin + marginLayoutParams.bottomMargin;

            if (widthUsed + childUsedWidth < widthSpecSize) {
                widthUsed += childUsedWidth;
                if (childUsedHeight > childMaxHeightOfThisLine) {
                    childMaxHeightOfThisLine = childUsedHeight;
                }
            } else {
                heightUsed += childMaxHeightOfThisLine + verticalSpacing;
                widthUsed = paddingLeft + paddingRight + childUsedWidth;
                childMaxHeightOfThisLine = childUsedHeight;
            }

        }

    }

    heightUsed += childMaxHeightOfThisLine;
    setMeasuredDimension(widthSpecSize, heightUsed);
}


@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int paddingLeft = getPaddingLeft();
    int paddingTop = getPaddingTop();


    int childStartLayoutX = paddingLeft;
    int childStartLayoutY = paddingTop;

    int widthUsed = 0;

    int childMaxHeight = 0;

    int childCount = getChildCount();

    for (int i = 0; i < childCount; i++) {
        View child = getChildAt(i);
        if (child.getVisibility() != GONE) {
            int childNeededWidth, childNeedHeight;
            int left, top, right, bottom;

            int childMeasuredWidth = child.getMeasuredWidth();
            int childMeasuredHeight = child.getMeasuredHeight();

            LayoutParams childLayoutParams = child.getLayoutParams();
            MarginLayoutParams marginLayoutParams = (MarginLayoutParams) childLayoutParams;
            int childLeftMargin = marginLayoutParams.leftMargin;
            int childTopMargin = marginLayoutParams.topMargin;
            int childRightMargin = marginLayoutParams.rightMargin;
            int childBottomMargin = marginLayoutParams.bottomMargin;
            childNeededWidth = childLeftMargin + childRightMargin + childMeasuredWidth;
            childNeedHeight = childTopMargin + childBottomMargin + childMeasuredHeight;

            if (widthUsed + childNeededWidth+childLeftMargin + childRightMargin<= r - l) {
                if (childNeedHeight > childMaxHeight) {
                    childMaxHeight = childNeedHeight;
                }
                left = childStartLayoutX + childLeftMargin;
                top = childStartLayoutY + childTopMargin;
                right = left + childMeasuredWidth;
                bottom = top + childMeasuredHeight;
                widthUsed =right+ childNeededWidth;
                childStartLayoutX += childNeededWidth;
            } else {
                childStartLayoutY += childMaxHeight + verticalSpacing;
                childStartLayoutX = paddingLeft;
                widthUsed = paddingLeft + paddingRight;
                left = childStartLayoutX + childLeftMargin;
                top = childStartLayoutY + childTopMargin;
                right = left + childMeasuredWidth;
                bottom = top + childMeasuredHeight;
                widthUsed =right+ childNeededWidth;
                childStartLayoutX += childNeededWidth;
                childMaxHeight = childNeedHeight;
            }
            child.layout(left, top, right, bottom);
        }
    }
}
}

2-:重写onMeasure():
-1:获取view的Mode和Size;
-2:计算View在水平和垂直方向已经使用的大小,padding;
-3:计量每个子view的宽高,以及padding或者margin;
-4:measureChild()可以测量子view的大小;

3-:使用:
-1:获取到自定义view;
-2:获取到view的layout;
-3:使用addview();

 public class MainActivity extends AppCompatActivity {
           MyFlowLayout layout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    layout=(MyFlowLayout)findViewById(R.id.main_view);

    ViewGroup.LayoutParams childLayoutParams = layout.getLayoutParams();
    ViewGroup.MarginLayoutParams marginLayoutParams = (ViewGroup.MarginLayoutParams) childLayoutParams;

    View view=LayoutInflater.from(MainActivity.this).inflate(R.layout.mian_view,null);

    View view1=LayoutInflater.from(MainActivity.this).inflate(R.layout.mian_view,null);

    layout.addView(view,marginLayoutParams);

    layout.addView(view1,marginLayoutParams);
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值