美文网首页
自定义流式布局 MyFlowLayout

自定义流式布局 MyFlowLayout

作者: sometimes_ | 来源:发表于2019-05-16 19:26 被阅读0次

自定义流式布局,只对match_parent、padding进行了处理、子view的margin未进行处理(可通过horizontal_spacing属性处理子view水平间距 ,vertical_spacing处理行间距)
一、基本实现逻辑
1.成员

private float vertical_spacing= 20f; //默认行间距
private float horizontal_spacing = 20f;//默认view间距

2.读取自定义属性,赋值间距

@SuppressLint("CustomViewStyleable")
TypedArray array= context.obtainStyledAttributes(attrs, R.styleable.MyFlowLayout);
horizontal_spacing = array.getDimension(R.styleable.MyFlowLayout_horizontal_spacing,    horizontal_spacing);
vertical_spacing = array.getDimension(R.styleable.MyFlowLayout_vertical_spacing, vertical_spacing);
array.recycle();

3.重写onMeasure、onLayout方法

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width= MeasureSpec.getSize(widthMeasureSpec);
        int mode_width= MeasureSpec.getMode(widthMeasureSpec);
        int currentLineUsedWidth= getPaddingLeft() + getPaddingRight();
        int parentViewHeight= getPaddingTop() + getPaddingBottom();
        if (mode_width!= MeasureSpec.EXACTLY) {
            throw new Error("Pleach set view width_size to Match_parent");
        } else {
            //由于flowLayout设置最大  只需计算 高度就可
            int childSize= getChildCount();
            for (int i= 0; i< childSize; i++) {
                View view= getChildAt(i);
                measureChild(view, widthMeasureSpec, heightMeasureSpec);
                if (i== 0) {
                    parentViewHeight+= view.getMeasuredHeight();
                }

                if (currentLineUsedWidth!= getPaddingLeft() + getPaddingRight() &&
                        view.getMeasuredWidth() + horizontal_spacing > width- currentLineUsedWidth) {
                    currentLineUsedWidth= getPaddingLeft() + getPaddingRight(); //重置下一行宽
                    parentViewHeight+= view.getMeasuredHeight() + vertical_spacing;
                }
                if (currentLineUsedWidth!= getPaddingLeft() + getPaddingRight()) {
                    currentLineUsedWidth+= horizontal_spacing;
                }
                currentLineUsedWidth+= view.getMeasuredWidth();
                }
                }
        setMeasuredDimension(width, parentViewHeight);
  }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        //定位所有子view的位置  左上右下
        int width= getMeasuredWidth();
        int lastViewHeight= 0;
        int size= getChildCount();
        int left= getPaddingLeft();
        int top= getPaddingTop();
        int right;
        int bottom;
        for (int i= 0; i< size; i++) {
            View view= getChildAt(i);
            //定位当前子view位置
            int view_height= view.getMeasuredHeight();
            int viwe_width= view.getMeasuredWidth();
            if (viwe_width+ getPaddingRight() > width- left) {
                //换行定位
                left= getPaddingLeft();
                top+= lastViewHeight+ vertical_spacing;
            }
            right= left+ viwe_width;
            bottom= top+ view_height;
            view.layout(left, top, right, bottom);
            lastViewHeight= view_height;
            left+= viwe_width+ horizontal_spacing; //加上间距
        }
}

二、自定义属性

<declare-styleable name ="MyFlowLayout">
      <attr name = "vertical_spacing" format ="dimension"/>
      <attr name ="horizontal_spacing" format="dimension"/>
</declare-styleable>

相关文章

网友评论

      本文标题:自定义流式布局 MyFlowLayout

      本文链接:https://www.haomeiwen.com/subject/viswaqtx.html