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

Posted time_iter

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);


以上是关于Android--View自定义—标签<流式布局;的主要内容,如果未能解决你的问题,请参考以下文章

模仿微信标签功能的自动换行线性布局(自定义流式标签组件)

模仿微信标签功能的自动换行线性布局(自定义流式标签组件)

Android中常见的热门标签的流式布局的实现

自定义流式布局

Android之自定义流式布局FlowLayout

Android 自定义ViewGroup之实现FlowLayout-标签流容器