美文网首页
Android自定义View(一)流失布局FlowLayout

Android自定义View(一)流失布局FlowLayout

作者: digtal_ | 来源:发表于2018-07-28 18:44 被阅读35次
    A18823137F61E6A21141DB7FEF73A42B.png

    实现步骤

    1.写一个类FlowLayout 继承ViewGroup
    2.在onMeasure方法中计算得到控件的宽高,思路就是计算每个子孩子的宽高当子孩子的宽度相加大于控件宽度就换行,高度累加

      @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int widthMode = MeasureSpec.getMode(widthMeasureSpec);
            int heightMode = MeasureSpec.getMode(heightMeasureSpec);
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSize = MeasureSpec.getSize(heightMeasureSpec);
            //定义控件宽度
            int width = 0;
            //定义控件高度
            int height = 0;
            //定义每行最大宽度
            int lineWidth = 0;
            //定义每行最大高度
            int lineHeight = 0;
            for (int i = 0; i < getChildCount(); i++) {
                View child = getChildAt(i);
                measureChild(child,widthMeasureSpec, heightMeasureSpec);
                MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
                int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
                int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
    
                if (lineWidth + childWidth > widthSize) {//大于控件宽度换行
                    width = Math.max(lineWidth, width);
                    height += lineHeight;
                    lineWidth = childWidth;
                    lineHeight = childHeight;
    
                } else {
                    lineWidth += childWidth;
                    lineHeight = Math.max(childHeight, lineHeight);
                }
                if (i == getChildCount() - 1) {//如果是最后一个子控件要计算他的宽高再算进去
                    width = Math.max(lineWidth, width);
                    height += lineHeight;
                }
    
            }
    
            setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthSize : width,
                    heightMode == MeasureSpec.EXACTLY ? heightSize : height);
            Log.e("width", "width = " + width);
            Log.e("height", "height = " + height);
        }
    
    

    3.其中要注意的是getLayoutParams方法要在类中重写generateLayoutParams方法否则是拿不到子孩子的margin值

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

    4.最后就是子孩子的具体怎么摆放了思路和测量中的方法差不多

     @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            //定义每行最大宽度
            int lineWidth = 0;
            //定义每行最大高度
            int lineHeight = 0;
            int left = 0;
            int top = 0;
            for (int i = 0; i < getChildCount(); i++) {
                View child = getChildAt(i);
    
                MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
                int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
                int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
    
                if (lineWidth + childWidth > getMeasuredWidth()) {//大于控件宽度换行
                    top += lineHeight;
                    //换行把left值为0
                    left = 0;
                    lineWidth = childWidth;
                    lineHeight = childHeight;
    
                } else {
                    lineWidth += childWidth;
                    lineHeight = Math.max(childHeight, lineHeight);
                }
                int lc = left + lp.leftMargin;
                int tc = top + lp.topMargin;
                int rc = lc + child.getMeasuredWidth();
                int bc = tc + child.getMeasuredHeight();
                child.layout(lc, tc, rc, bc);
                left += childWidth;
            }
    
        }
    
    
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimary">
    
        <com.chinamall21.mobile.animstudy.view.FlowLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <TextView
                style="@style/style_flow"
                android:text="it工程师"/>
    
            <TextView
                style="@style/style_flow"
                android:text="ANDORID"/>
    
            <TextView
                style="@style/style_flow"
                android:text="IOS"/>
    
            <TextView
                style="@style/style_flow"
                android:text="JAVA开发"/>
    
            <TextView
                style="@style/style_flow"
                android:text="产品经理啊"/>
    
        <style name="style_flow">
            <item name="android:textColor">#fff</item>
            <item name="android:padding">10dp</item>
            <item name="android:layout_marginLeft">6dp</item>
            <item name="android:layout_marginTop">6dp</item>
            <item name="android:layout_width">wrap_content</item>
            <item name="android:background">@drawable/shpae_circle</item>
            <item name="android:layout_height">wrap_content</item>
        </style>
    

    相关文章

      网友评论

          本文标题:Android自定义View(一)流失布局FlowLayout

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