美文网首页Android开发
11 自定义ViewGroup实现流式布局

11 自定义ViewGroup实现流式布局

作者: 凤邪摩羯 | 来源:发表于2020-11-18 09:25 被阅读0次

思考

流式布局:将子view,按顺序摆放在每一行,如果当前行的剩余宽度不够摆放下一个控件的时候,则换行摆放.控件之间的距离,可设置为自定义属性.

1. 自定义属性:声明,设置,解析获取自定义值

在attr.xml 声明:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="FlowLayout">
        <attr name="android:gravity" />
        <attr name="horizonSpacing" format="dimension|reference"/>
    </declare-styleable>
</resources>

2. 解析并重写方法

 public static class LayoutParams extends MarginLayoutParams {

        public int gravity = -1;

        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);

            TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.FlowLayout_Layout);
            try {
                gravity = a.getInt(R.styleable.FlowLayout_Layout_android_layout_gravity, -1);
            } finally {
                a.recycle();
            }


        }

        public LayoutParams(int width, int height) {
            super(width, height);
        }

        public LayoutParams(ViewGroup.LayoutParams source) {
            super(source);
        }

 }
 @Override
    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
        return new LayoutParams(p);
    }


    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new LayoutParams(getContext(), attrs);
    }


    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    }

    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        return super.checkLayoutParams(p) && p instanceof LayoutParams;
    }

3. 测量:

MeasureSpec=测量模式+测量大小 .

3.1先调用super测量自己

3.2 遍历所有的子View,对子View进行测量

子view的MeasureSpec值由父view的MeasureSpec值和自身的LayoutParams决定

3.3 计算出测量值measuredWidthmeasuredHeight并调用setMeasuredDimension(int measuredWidth, int measuredHeight)

  • measuredWidth
    MeasureSpec为EXACTLY时: measuredWidth=MeasureSpec.getSize(widthMeasureSpec)
    MeasureSpec为AT_MOST时: measuredWidth=布局中最宽的一行
  • measuredHeight
    MeasureSpec为EXACTLY时: measuredHeight=MeasureSpec.getSize(heightMeasureSpec)
    MeasureSpec为AT_MOST时: measuredHeight=布局中所有行的高度之和
    注意
    处理子view的lp.heigth = match_parent的情况,避免其撑满整个屏幕.

4. 布局:

在onLayout方法里面根据自己规则来确定children的位置

  • 注意:
    (1) 考虑布局子View摆放时候的L和T坐标
    (2) 考虑布局magin等

5. 绘制:onDraw

6. 处理LayoutParams

7. 触摸反馈:滑动事件

  • 事件拦截
  • 事件处理
    注意:
    (1) 滑动出现的无效果问题
    (2) 考虑滑动的越界问题处理

相关文章

网友评论

    本文标题:11 自定义ViewGroup实现流式布局

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