自定义View-自动换行的标签控件

android自定义换行标签:最近项目中需要实现一个功能:

网上有很多可以用的开源控件,我自己也学习写了一个自定义换行标签,让一个View继承ViewGroup,重写onmeasure()和onlayout()方法,核心代码如下大笑



   
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        //最后测量宽度和高度
        int resultWidth = 0;
        int resultHeigh = 0;
        //临时测量宽度和高度
        int linewidth = 0;
        int lineHeight = 0;
        int childCount = getChildCount();
        //测量控件的宽高模式  在之前文章中有讲过这个用法,不懂的可以看下
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);

        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);
            //测量每一个子view的宽和高
            measureChild(childView, widthMeasureSpec, heightMeasureSpec);
            //获取测量的高度
            int childWidth = childView.getMeasuredWidth();
            int childHeight = childView.getMeasuredHeight();
            //因为子View可能设置margin,这里要加上margin的距离
            MarginLayoutParams mlp = (MarginLayoutParams) childView.getLayoutParams();
            //子控件真实宽度和高度
            int realwidth = mlp.leftMargin + childWidth + mlp.rightMargin;
            int realHight = mlp.topMargin + childHeight + mlp.bottomMargin;

            //计算宽度
            if (linewidth + realwidth > widthSize) {
                //换行
                resultWidth = Math.max(linewidth, realwidth);
                resultHeigh = resultHeigh + realHight;
                //换行后高度和宽度重新计算
                linewidth = realwidth;
                lineHeight = realHight;
            } else {
                linewidth = linewidth + realwidth;
                lineHeight = Math.max(lineHeight, realHight);
            }
        }
        //保存测量完成后的宽度和高度
        setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthSize : resultWidth,
                heightMode == MeasureSpec.EXACTLY ? heightSize : resultHeigh);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        //子控件左边距离和上边距离
        int childleft = 0;
        int childtop = 0;
        //为每个孩子布局
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View childView = getChildAt(i);

            int measuredHeight = childView.getMeasuredHeight();
            int measuredWidth = childView.getMeasuredWidth();

            //因为子View可能设置margin,这里要加上margin的距离
            MarginLayoutParams mlp = (MarginLayoutParams) childView.getLayoutParams();
            if (childleft + mlp.leftMargin + mlp.rightMargin + measuredWidth > getWidth()) {
                //换行上边距离增加,左边距离为0
                childtop = childtop + mlp.topMargin + mlp.bottomMargin + measuredHeight;
                childleft = 0;
            }
	    //计算子控件
            int left = childleft + mlp.leftMargin;
            int top = childtop + mlp.topMargin;
            int right = childleft + mlp.leftMargin + mlp.rightMargin + measuredWidth;
            int bottom = childtop + mlp.topMargin + mlp.bottomMargin + measuredHeight;
	    //布局子控件
            childView.layout(left, top, right, bottom);
            //不换行左边距离是前面子控件宽度之和
            childleft = childleft + mlp.leftMargin + mlp.rightMargin + measuredWidth;

        }
    }
	
	这样我们基本完成了该控件的绘制,我们通过addview加入子控件,例如:	
	public void setTextviewRes(List<TextView> textviews) {
  	  //添加文字
  	  //先移除所有的子view
  	  removeAllViews();
  	  for (int i = 0; i < textviews.size(); i++) {
  	      TextView textView = textviews.get(i);
   	     addView(textView);
   	 }
   	 //重新布局
  	  requestLayout();
	}
	
	我们使用控件,调用控件的settextviewres()方法,以textview为例子,
	传入添加好的textview的集合(这里可以任意设置,功能需求是什么就可以按照自己的需求去更改)。
	这样就完成自定义换行标签大笑

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值