zoukankan      html  css  js  c++  java
  • Android自定义ViewGroup,实现自动换行

    学习《Android开发艺术探索》中自定义ViewGroup章节

    自定义ViewGroup总结的知识点

    一.自定义ViewGroup中,onMeasure理解

       onMeasure(int widthMeasureSpec,int heightMeasureSpec); 需要进行补充的逻辑

       1.对布局设置为wrap_content的兼容,具体查看下一篇日志的构建MeasureSpec的方法

      最终实现是在onMeasure(...)方法中对LayoutParams设置为wrap_content的实现,在构建MeasureSpec时将,这个转换为MeasureSpec.AT_MOST这样的设置模式

    注:下面模式一般适用于单View(不包括ViewGroup),因为ViewGroup设置为wrap_content时,是测量所有子View高/宽的和

    单View

    if(widthMode == MeasureSpec.AT_MOST && height == MeasureSpec.AT_MOST){
       setMeasureDimission(测量的宽,测量的高);
    }else if(widthMode == MeasureSpec.AT_MOST ){
       setMeasureDimission(测量的宽,heightMeasureSpec);//heightMeasureSpec是父布局指定
    }else if(heightMode == MeasureSpec.AT_MOST ){
       setMeasureDimission(widthMeasureSpec,测量的高);//widthMeasureSpec是父布局指定
    }

    ViewGroup(此方法在ViewGroup中已经实现,在自定义ViewGroup中可直接调用)

      /**
         * Utility to reconcile a desired size and state, with constraints imposed
         * by a MeasureSpec.  Will take the desired size, unless a different size
         * is imposed by the constraints.  The returned value is a compound integer,
         * with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and
         * optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the resulting
         * size is smaller than the size the view wants to be.
         *
         * @param size How big the view wants to be
         * @param measureSpec Constraints imposed by the parent
         * @return Size information bit mask as defined by
         * {@link #MEASURED_SIZE_MASK} and {@link #MEASURED_STATE_TOO_SMALL}.
         */
        public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
            int result = size;
            int specMode = MeasureSpec.getMode(measureSpec);
            int specSize =  MeasureSpec.getSize(measureSpec);
            switch (specMode) {
            case MeasureSpec.UNSPECIFIED:
                result = size;
                break;
            case MeasureSpec.AT_MOST:
                if (specSize < size) {
                    result = specSize | MEASURED_STATE_TOO_SMALL;
                } else {
                    result = size;
                }
                break;
            case MeasureSpec.EXACTLY:
                result = specSize;
                break;
            }
            return result | (childMeasuredState&MEASURED_STATE_MASK);
        }
    

      

    2.onMeasure方法中参数的理解,widthMeasureSpec和heightMeasureSpec,在布局中去掉了margin参数后的值,将测量值通过setMeasureDimission设置该布局的宽和高

          理解如下图

          

          

       二,自定义ViewGroup中,onLayout的理解

           1.onLayout(boolean changed, int l, int t, int r, int b) 对方法中参数,changed为当前布局是否改变

              l,t,r,b是当前的布局的参数坐标,即有 当前控件宽度 width = r - l  高度 height = b - t;这里包括了padding的值

     注意:在自定义ViewGroup的时候,实际计算得到的宽高均需要加入padding的值和子布局的margin值,而onMeasure或onLayout方法中传递过来的值,均不包含padding的值,这里要减去

       总结:ViewGroup本身计算不用加入ViewGroup本身的margin,但要考虑padding变化,同时要考虑子View中margin的值

       以上方法均需要调用子布局的measure和layout方法

      例子: 自定义有自动换行功能的ViewGroup

    package com.tongcheng.android.travel.widget;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.util.AttributeSet;
    import android.view.View;
    import android.view.ViewGroup;
    
    import com.tongcheng.android.R;
    
    
    /**
     * Created by lcl11718 on 2016/12/6.
     * 横向实现自动换行的ViewGroup
     */
    
    public class HorizontalWrapLineLayout extends ViewGroup {
    
        private int mVerticalSpace;
        private int mHorizontalSpace;
    
        public HorizontalWrapLineLayout(Context context) {
            this(context, null);
        }
    
        public HorizontalWrapLineLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context, attrs);
        }
    
        private void init(Context context, AttributeSet attrs) {
            setAttributeSet(context, attrs);
        }
    
        /**
         * 设置自定义属性
         *
         * @param context
         * @param attrs
         */
        private void setAttributeSet(Context context, AttributeSet attrs) {
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HorizontalWrapLineLayout);
            //属性中定义左右边距 padding margin
            //属性中定义每一个距离垂直方向vertalSpace 和水平方向horizontalSpace
            mVerticalSpace = (int) a.getDimension(R.styleable.HorizontalWrapLineLayout_verticalWrapSpace, 0);
            mHorizontalSpace = (int) a.getDimension(R.styleable.HorizontalWrapLineLayout_horizontalWrapSpace, 0);
            a.recycle();
        }
    
        @Override
        protected LayoutParams generateDefaultLayoutParams() {
            return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        }
    
        @Override
        protected LayoutParams generateLayoutParams(LayoutParams p) {
            return new MarginLayoutParams(p);
        }
    
        @Override
        public LayoutParams generateLayoutParams(AttributeSet attrs) {
            return new MarginLayoutParams(getContext(), attrs);
        }
    
        @Override
        protected boolean checkLayoutParams(LayoutParams p) {
            return p instanceof MarginLayoutParams;
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            // 这里的高度和宽度是去掉margin的值
            int horizontalPadding = getPaddingLeft() + getPaddingRight();
            int measureWidth = horizontalPadding;
            int verticalPadding = getPaddingTop() + getPaddingBottom();
            int measureHeight = verticalPadding;
            final int childCount = getChildCount();
    
            int widthSpaceSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSpaceMode = MeasureSpec.getMode(heightMeasureSpec);
            if (childCount == 0) {
                setMeasuredDimension(0, 0);
                return;
            }
            for (int i = 0; i < childCount; i++) {
                View childView = getChildAt(i);
                //测量子View
                if (childView.getVisibility() != View.GONE) {
                    measureChildWithMargins(childView, widthMeasureSpec, 0, heightMeasureSpec, 0);
                    MarginLayoutParams lp = (MarginLayoutParams) childView.getLayoutParams();
                    int childMeasuredHeight = childView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
                    int childMeasuredWidth = childView.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
                    measureWidth += childMeasuredWidth + mHorizontalSpace;
                    if (measureWidth > widthSpaceSize) {
                        measureHeight += childMeasuredHeight + mVerticalSpace;
                        measureWidth = getPaddingLeft() + getPaddingRight();
                    }
                    if (childCount - 1 == i && measureWidth > 0) {
                        measureHeight += childMeasuredHeight + mVerticalSpace;
                    }
                }
            }
            if (heightSpaceMode == MeasureSpec.AT_MOST) {
                setMeasuredDimension(widthMeasureSpec, measureHeight);
            } else {
                setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
            }
        }
    
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            //这里的四角参数,是去掉Margin的参数
            int childCount = getChildCount();
            int left = getPaddingLeft();
            int top = getPaddingTop();
            int right = r - getPaddingRight();
    
            int currentLeft = left;
            int currentTop = top;
            int lineHeight = 0;
            for (int i = 0; i < childCount; i++) {
                View childView = getChildAt(i);
                MarginLayoutParams lp = (MarginLayoutParams) childView.getLayoutParams();
                //确定4个点
                if (currentLeft + childView.getMeasuredWidth() + lp.leftMargin + lp.rightMargin >= right) {//换行
                    currentLeft = left;
                    currentTop += lineHeight + mVerticalSpace;
                    lineHeight = childView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
                } else {
                    lineHeight = Math.max(lineHeight, childView.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
                }
                childView.layout(
                        currentLeft + lp.leftMargin,
                        currentTop + lp.topMargin,
                        currentLeft + lp.leftMargin + childView.getMeasuredWidth(),
                        currentTop + lp.topMargin + childView.getMeasuredHeight());
                currentLeft += childView.getMeasuredWidth() + lp.leftMargin + lp.rightMargin + mHorizontalSpace;
            }
        }
    }

      上个版本是简略的实现,下面是优化之后,这个版本支持Grivity布局

    package com.tongcheng.android.travel.widget;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.util.AttributeSet;
    import android.util.LayoutDirection;
    import android.view.Gravity;
    import android.view.View;
    import android.view.ViewGroup;
    
    import com.tongcheng.android.R;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Created by lcl11718 on 2016/12/8.
     * 自动换行容器
     */
    
    public class AutoRowLayout extends ViewGroup {
    
        /**
         * 平均分配
         */
        public static final int AVERAGE = 0;
        /**
         * 自适应
         */
        public static final int ADAPTIVE = 1;
        /**
         * style
         */
        private int mStyleType;
        /**
         * 列之间间距
         */
        private int mColumnSpace;
        /**
         * 行之间间距
         */
        private int mRowSpace;
        /**
         * 列数量
         */
        private int mColumnNum;
        /**
         * 行数
         */
        private int mRowNum;
    
        /**
         * 最大行数
         */
        private int mMaxLine;
        /**
         * 对齐方式
         */
        private int mGravity = Gravity.START | Gravity.TOP;
    
        /**
         * 自适应测量算法 记录行数
         */
        private List<Integer> mAdaptiveLines = new ArrayList<Integer>();
    
        public AutoRowLayout(Context context) {
            this(context, null, 0);
        }
    
        public AutoRowLayout(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public AutoRowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            setAttributes(context, attrs);
        }
    
        /**
         * set basic attrs
         *
         * @param context
         * @param attrs
         */
        public void setAttributes(Context context, AttributeSet attrs) {
            TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.AutoRowLayout);
            mStyleType = ta.getInt(R.styleable.AutoRowLayout_style_type, 0);//0 是平均分
            mColumnSpace = (int) ta.getDimension(R.styleable.AutoRowLayout_columnSpace, 0);
            mRowSpace = (int) ta.getDimension(R.styleable.AutoRowLayout_rowSpace, 0);
            mColumnNum = ta.getInt(R.styleable.AutoRowLayout_columnNum, 0);
            mRowNum = ta.getInt(R.styleable.AutoRowLayout_rowNum, 0);
            mMaxLine = ta.getInt(R.styleable.AutoRowLayout_maxLine, 0);
            mGravity = ta.getInt(R.styleable.AutoRowLayout_android_gravity, 0);
            ta.recycle();
        }
    
        /**
         * set style type
         *
         * @param type
         */
        public void setStyleType(int type) {
            this.mStyleType = type;
        }
    
        public void setColumnSpace(int columnSpace) {
            this.mColumnSpace = columnSpace;
        }
    
        public void setRowSpace(int rowSpace) {
            this.mRowSpace = rowSpace;
        }
    
        public void setColumnNum(int columnNum) {
            this.mColumnNum = columnNum;
        }
    
        public void setRowNum(int rowNum) {
            this.mRowNum = rowNum;
        }
    
        public void setGravity(int gravity) {
            this.mGravity = gravity;
        }
    
    
        /***********************************
         * 加入Margin start
         **************************************/
        @Override
        protected LayoutParams generateDefaultLayoutParams() {
            return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        }
    
        @Override
        public LayoutParams generateLayoutParams(AttributeSet attrs) {
            return new MarginLayoutParams(getContext(), attrs);
        }
    
        @Override
        protected LayoutParams generateLayoutParams(LayoutParams p) {
            return new MarginLayoutParams(p);
        }
    
        @Override
        protected boolean checkLayoutParams(LayoutParams p) {
            return p != null && p instanceof MarginLayoutParams;
        }
    
        /***********************************
         * 加入Margin end
         **************************************/
    
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            if (mStyleType == AVERAGE) {
                measureAverage(widthMeasureSpec, heightMeasureSpec);
            } else if (mStyleType == ADAPTIVE) {
                measureAdaptive(widthMeasureSpec, heightMeasureSpec);
            }
        }
    
        /**
         * 平均测量算法
         *
         * @param widthMeasureSpec
         * @param heightMeasureSpec
         */
        private void measureAverage(int widthMeasureSpec, int heightMeasureSpec) {
            int count = getChildCount();
            if (count == 0) {
                setMeasuredDimension(0, 0);
                return;
            }
    
            int widthPadding = getPaddingLeft() + getPaddingRight();
            int heightPadding = getPaddingTop() + getPaddingBottom();
            int childState = 0;
            // get a max child width for widthMeasureSpec
            int maxChildWidth = getMaxChildWidth(count, widthMeasureSpec, heightMeasureSpec, childState);
            int maxWidth = 0;
    
            if (mColumnNum > 0) {
                maxWidth = maxChildWidth * mColumnNum + (mColumnNum - 1) * mColumnSpace + widthPadding;
            } else {
                throw new RuntimeException("autoRowLayout must set a column num");
            }
    
            int widthMeasureSize = MeasureSpec.getSize(widthMeasureSpec);
            int widthMeasureMode = MeasureSpec.getMode(widthMeasureSpec);
    
            View firstChild = getChildAt(0);
            int totalRowNumHeight = mRowNum * firstChild.getMeasuredHeight() + (mRowNum - 1) * mRowSpace + heightPadding;
            int maxHeight = mRowNum > 0 ? totalRowNumHeight : getTotalHeightNoRows(count, heightPadding, firstChild);
    
            int limitMaxWidth = (widthMeasureSize - widthPadding - (mColumnNum - 1) * mColumnSpace) / mColumnNum;
            int maxAllowWidth = MeasureSpec.EXACTLY == widthMeasureMode ? limitMaxWidth : Math.min(maxChildWidth, limitMaxWidth);
            setWidthLayoutParams(count, maxAllowWidth);
    
            maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
            int heightAndState = resolveSizeAndState(maxHeight, heightMeasureSpec, 0);
            setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState), heightAndState);
        }
    
        /**
         * set per max width  of views
         *
         * @param count
         * @param maxChildWidth
         */
        private void setWidthLayoutParams(int count, int maxChildWidth) {
            for (int index = 0; index < count; index++) {
                View child = getChildAt(index);
                if (child.getVisibility() == View.GONE) {
                    continue;
                }
                MarginLayoutParams lp = new MarginLayoutParams(maxChildWidth, child.getLayoutParams().height);
                child.setLayoutParams(lp);
            }
        }
    
        /**
         * get max height not set row num
         *
         * @param count
         * @param heightPadding
         * @param child
         * @return
         */
        private int getTotalHeightNoRows(int count, int heightPadding, View child) {
    
            int allowRowNums = count / mColumnNum;
            int maxHeight = allowRowNums * child.getMeasuredHeight() + (allowRowNums - 1) * mRowSpace + heightPadding;
    
            if (count % mColumnNum > 0) {
                maxHeight += child.getMeasuredHeight() + mRowSpace;
            }
            return maxHeight;
        }
    
        /**
         * get a max child width for this layout
         *
         * @param count
         * @param widthMeasureSpec
         * @param heightMeasureSpec
         * @return
         */
        private int getMaxChildWidth(int count, int widthMeasureSpec, int heightMeasureSpec, int childState) {
            int maxChildWidth = 0;
            for (int index = 0; index < count; index++) {
                View child = getChildAt(index);
                if (child.getVisibility() == View.GONE) {
                    continue;
                }
                measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
                MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
                childState = combineMeasuredStates(childState, child.getMeasuredState());
                maxChildWidth = Math.max(maxChildWidth, child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
            }
            return maxChildWidth;
        }
    
    
        /**
         * 自适应测量算法
         *
         * @param widthMeasureSpec
         * @param heightMeasureSpec
         */
        private void measureAdaptive(int widthMeasureSpec, int heightMeasureSpec) {
            int count = getChildCount();
            if (count == 0) {
                setMeasuredDimension(0, 0);
                return;
            }
            int widthPadding = getPaddingLeft() + getPaddingRight();
            int heightPadding = getPaddingTop() + getPaddingBottom();
            int width = widthPadding;
            int height = heightPadding;
            int lineMaxHeight = 0;
    
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            int childState = 0;
            mAdaptiveLines.clear();
            for (int index = 0; index < count; index++) {
                View child = getChildAt(index);
                if (child.getVisibility() == View.GONE) {
                    continue;
                }
                measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
                MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
                if (width + child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin > widthSize) {//换行
                    height += lineMaxHeight + mRowSpace;
                    width = widthPadding + child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin + mColumnSpace;
                    lineMaxHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
                    mAdaptiveLines.add(index);
                } else {
                    lineMaxHeight = Math.max(lineMaxHeight, child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
                    width += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin + mColumnSpace;
                    childState = combineMeasuredStates(childState, child.getMeasuredState());
                }
            }
            mAdaptiveLines.add(count);
            height += lineMaxHeight;
    
            height = Math.max(height, getSuggestedMinimumHeight());
            int heightAndState = resolveSizeAndState(height, heightMeasureSpec, 0);
            setMeasuredDimension(resolveSizeAndState(width, widthMeasureSpec, childState), heightAndState);
        }
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            if (mStyleType == AVERAGE) {
                layoutAverage(l, t, r, b);
            } else if (mStyleType == ADAPTIVE) {
                layoutAdaptive(l, t, r, b);
            }
        }
    
    
        /**
         * 平均布局算法
         *
         * @param left
         * @param top
         * @param right
         * @param bottom
         */
        private void layoutAverage(int left, int top, int right, int bottom) {
            int count = getChildCount();
            if (count == 0) {
                return;
            }
            int childLeft;
            int childTop = 0;
            int lineMaxHeight = 0;
    
            int totalRowNum = count / mColumnNum + (count % mColumnNum == 0 ? 0 : 1);
    
            int maxRowNum = mRowNum > 0 ? mRowNum : totalRowNum;
    
            for (int rowNum = 0; rowNum < maxRowNum; rowNum++) {
                childLeft = getPaddingLeft();
                childTop += rowNum > 0 ? lineMaxHeight + mRowSpace : getPaddingTop();
                for (int columnNum = 0; columnNum < mColumnNum; columnNum++) {
                    if (columnNum + mColumnNum * rowNum >= count) {
                        break;
                    }
                    View child = getChildAt(columnNum + mColumnNum * rowNum);
                    if (child.getVisibility() == View.GONE) {
                        continue;
                    }
                    MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
    
                    child.layout(
                            childLeft + lp.leftMargin,
                            childTop + lp.topMargin,
                            childLeft + lp.leftMargin + lp.width,
                            childTop + lp.topMargin + lp.height);
                    childLeft += lp.width + lp.leftMargin + lp.rightMargin + mColumnSpace;
                    lineMaxHeight = Math.max(lineMaxHeight, lp.height + lp.topMargin + lp.bottomMargin);
                }
            }
        }
    
        /**
         * 自适应布局算法
         *
         * @param left
         * @param top
         * @param right
         * @param bottom
         */
        private void layoutAdaptive(int left, int top, int right, int bottom) {
            int count = getChildCount();
            if (count == 0) {
                return;
            }
            int width = right - left;
            int childSpace = width - getPaddingLeft() - getPaddingRight();
    
            int limitLines = mMaxLine > 0 ? Math.min(mMaxLine, mAdaptiveLines.size()) : mAdaptiveLines.size();
            int[] childLefts = new int[limitLines];
    
            int totalChildHeight = 0;
    
            for (int rowIndex = 0; rowIndex < limitLines; rowIndex++) {
                int startRowIndex = rowIndex > 0 ? mAdaptiveLines.get(rowIndex - 1) : 0;
                int endRowIndex = mAdaptiveLines.get(rowIndex);
                int maxChildWidth = 0;
                int lineMaxHeight = 0;
                for (; startRowIndex < endRowIndex; startRowIndex++) {
                    View child = getChildAt(startRowIndex);
                    if (child.getVisibility() == View.GONE) {
                        continue;
                    }
                    MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
                    maxChildWidth += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
                    if (startRowIndex != endRowIndex - 1) {
                        maxChildWidth += mColumnSpace;
                    }
                    lineMaxHeight = Math.max(lineMaxHeight, child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
                }
                totalChildHeight += lineMaxHeight;
                childLefts[rowIndex] = getChildLeft(childSpace - maxChildWidth);
            }
    
            int childTop = getChildTop(top, bottom, totalChildHeight);
            for (int rowIndex = 0; rowIndex < limitLines; rowIndex++) {
                int startRowIndex = rowIndex > 0 ? mAdaptiveLines.get(rowIndex - 1) : 0;
                int endRowIndex = mAdaptiveLines.get(rowIndex);
                int childLeft = childLefts[rowIndex];
                for (; startRowIndex < endRowIndex; startRowIndex++) {
                    View child = getChildAt(startRowIndex);
                    if (child.getVisibility() == View.GONE) {
                        continue;
                    }
                    MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
                    child.layout(
                            childLeft + lp.leftMargin,
                            childTop + lp.topMargin,
                            childLeft + lp.leftMargin + child.getMeasuredWidth(),
                            childTop + lp.topMargin + child.getMeasuredHeight());
                    childLeft += child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin + mColumnSpace;
                }
    
            }
        }
    
        /**
         * get top of child View
         *
         * @param top
         * @param bottom
         * @param totalChildHeight
         * @return
         */
        private int getChildTop(int top, int bottom, int totalChildHeight) {
            int childTop;
            final int majorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;
            switch (majorGravity) {
                case Gravity.BOTTOM:
                    // mTotalLength contains the padding already
                    childTop = getPaddingTop() + bottom - top - totalChildHeight;
                    break;
    
                // mTotalLength contains the padding already
                case Gravity.CENTER_VERTICAL:
                    childTop = getPaddingTop() + (bottom - top - totalChildHeight) / 2;
                    break;
    
                case Gravity.TOP:
                default:
                    childTop = getPaddingTop();
                    break;
            }
            return childTop;
        }
    
        /**
         * get left value of row
         *
         * @param widthSpace
         * @return
         */
        private int getChildLeft(int widthSpace) {
            int childLeft;
            final int minorGravity = mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
            final int absoluteGravity = Gravity.getAbsoluteGravity(minorGravity, LayoutDirection.LTR);
            switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
                case Gravity.CENTER_HORIZONTAL:
                    childLeft = getPaddingLeft() + (widthSpace / 2);
                    break;
    
                case Gravity.RIGHT:
                    childLeft = getPaddingLeft() + widthSpace;
                    break;
    
                case Gravity.LEFT:
                default:
                    childLeft = getPaddingLeft();
                    break;
            }
            return childLeft;
        }
    }
    

      

  • 相关阅读:
    微软收购以色列触控笔技术
    西少爷肉夹馍:我们依然是一家互联网公司
    刘强东哈佛演讲:留学生应回国 不要辜负时代
    与海外买家沟通技巧20招,总有一招适合您
    转:腾讯福利升级 今起员工购首套房可无息贷款最高50万元
    Action Required: Listings Deactivated for Potential Pricing Error
    转:为什么说招到合适的人比融到钱更加重要
    华为离职副总裁徐家骏:年薪千万的工作感悟
    how to update product listing price sale price and sale date using mobile App
    二零一五年正月初四
  • 原文地址:https://www.cnblogs.com/ghhryr-lichl/p/6141223.html
Copyright © 2011-2022 走看看