ViewGroup.MarginLayoutParams

原文地址:http://blog.csdn.net/wcs542882916

    /**

    * Per-child layoutinformation for layouts that support margins.

    * See

    * {@linkandroid.R.styleable#ViewGroup_MarginLayout ViewGroup Margin Layout Attributes}

    * for a list of all child view attributes that this class supports.

    */

   

    /* 每个子布局的布局信息,子布局是要支持margin(外边距)属性的。

    *

    * android.R.styleable.ViewGroup_MarginLayouts是这个类所支持的子控件的一个属性列表,子控件拥有这些属性

    *

    * 它继承于 ViewGroup.LayoutParams(只有宽高属性,宽高是包含padding的,即包含内边距)

    */

    public static class MarginLayoutParamsextends ViewGroup.LayoutParams {

       /**

        * The left margin in pixels of the child.

        * Call {@linkViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value

        * to this field.

        */

      

       /*

        * 子控件的左外边距,单位是像素

        */

       @ViewDebug.ExportedProperty(category="layout")

       public int leftMargin;

 

       /**

        * The top margin in pixels of the child.

        * Call {@linkViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value

        * to this field.

        */

       

       /*

        * 上外边距

        */

       @ViewDebug.ExportedProperty(category="layout")

       public int topMargin;

 

       /**

        * The right margin in pixels of the child.

        * Call {@linkViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value

        * to this field.

        */

       /*

        * 右外边距

        */

       @ViewDebug.ExportedProperty(category="layout")

       public int rightMargin;

 

       /**

        * The bottom margin in pixels of the child.

        * Call {@linkViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value

        * to this field.

        */

       /*

        * 下外边距

        */

       @ViewDebug.ExportedProperty(category="layout")

       public int bottomMargin;

 

       /**

        * The start margin in pixels of the child.

        * Call {@linkViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value

        * to this field.

        */

       

       /* 起始外边距

        * 默认是 DEFAULT_MARGIN_RELATIVE

        */

       @ViewDebug.ExportedProperty(category="layout")

       private int startMargin= DEFAULT_MARGIN_RELATIVE;

 

       /**

        * The end margin in pixels of the child.

        * Call {@linkViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value

        * to this field.

        */

        

       /* 末尾外边距

        * 默认是 DEFAULT_MARGIN_RELATIVE

        */

       @ViewDebug.ExportedProperty(category="layout")

       private int endMargin= DEFAULT_MARGIN_RELATIVE;

 

       /**

        * The default start and end margin.

        * @hide

        */

       /* 默认的起始和末尾外边距

        * -2147483648 (0x80000000)

        */

       public static final int DEFAULT_MARGIN_RELATIVE= Integer.MIN_VALUE;

 

       /**

        * Bit  0: layout direction

        * Bit  1: layout direction

        * Bit  2: left margin undefined

        * Bit  3: right margin undefined

        * Bit  4: is RTL compatibilitymode

        * Bit  5: need resolution

        *

        * Bit 6 to 7 not used

        *

        * @hide

        */

       @ViewDebug.ExportedProperty(category="layout",flagMapping = {

                @ViewDebug.FlagToString(mask=LAYOUT_DIRECTION_MASK,

                        equals = LAYOUT_DIRECTION_MASK,name ="LAYOUT_DIRECTION"),

                @ViewDebug.FlagToString(mask=LEFT_MARGIN_UNDEFINED_MASK,

                        equals = LEFT_MARGIN_UNDEFINED_MASK,name ="LEFT_MARGIN_UNDEFINED_MASK"),

                @ViewDebug.FlagToString(mask=RIGHT_MARGIN_UNDEFINED_MASK,

                        equals = RIGHT_MARGIN_UNDEFINED_MASK,name ="RIGHT_MARGIN_UNDEFINED_MASK"),

                @ViewDebug.FlagToString(mask=RTL_COMPATIBILITY_MODE_MASK,

                        equals = RTL_COMPATIBILITY_MODE_MASK,name ="RTL_COMPATIBILITY_MODE_MASK"),

                @ViewDebug.FlagToString(mask=NEED_RESOLUTION_MASK,

                        equals = NEED_RESOLUTION_MASK,name ="NEED_RESOLUTION_MASK")

       })

       byte mMarginFlags;

 

       private static final int LAYOUT_DIRECTION_MASK= 0x00000003;

       private static final int LEFT_MARGIN_UNDEFINED_MASK= 0x00000004;

       private static final int RIGHT_MARGIN_UNDEFINED_MASK= 0x00000008;

       private static final int RTL_COMPATIBILITY_MODE_MASK= 0x00000010;

       private static final int NEED_RESOLUTION_MASK= 0x00000020;

 

       private static final int DEFAULT_MARGIN_RESOLVED= 0;

       private static final int UNDEFINED_MARGIN=DEFAULT_MARGIN_RELATIVE;

 

       /**

        * Creates a new set of layout parameters. The values are extracted from

        * the supplied attributes set and context.

        *

        * @param c the application environment

        * @param attrs the set of attributes from which to extract the layout

        *              parameters' values

        */

       

       /* 创建一个新的布局参数集合,这个值是从已经应用的属性集和上下文中提取出来的

        * @param c 应用程序环境

        * @param attrs 属性集,用于提取布局参数值

        */

       publicMarginLayoutParams(Context c, AttributeSet attrs) {

           super();

 

           TypedArray a = c.obtainStyledAttributes(attrs,R.styleable.ViewGroup_MarginLayout);

           setBaseAttributes(a,

                   R.styleable.ViewGroup_MarginLayout_layout_width,

                   R.styleable.ViewGroup_MarginLayout_layout_height);

 

           intmargin = a.getDimensionPixelSize(

                   com.android.internal.R.styleable.ViewGroup_MarginLayout_layout_margin,-1);

           if(margin >= 0) {

                leftMargin = margin;

                topMargin = margin;

                rightMargin= margin;

                bottomMargin = margin;

           } else{

                leftMargin = a.getDimensionPixelSize(

                        R.styleable.ViewGroup_MarginLayout_layout_marginLeft,

                        UNDEFINED_MARGIN);

                if (leftMargin==UNDEFINED_MARGIN){

                    mMarginFlags |=LEFT_MARGIN_UNDEFINED_MASK;

                    leftMargin =DEFAULT_MARGIN_RESOLVED;

                }

                rightMargin = a.getDimensionPixelSize(

                       R.styleable.ViewGroup_MarginLayout_layout_marginRight,

                        UNDEFINED_MARGIN);

                if (rightMargin==UNDEFINED_MARGIN){

                    mMarginFlags |=RIGHT_MARGIN_UNDEFINED_MASK;

                    rightMargin =DEFAULT_MARGIN_RESOLVED;

                }

 

                topMargin = a.getDimensionPixelSize(

                       R.styleable.ViewGroup_MarginLayout_layout_marginTop,

                        DEFAULT_MARGIN_RESOLVED);

                bottomMargin = a.getDimensionPixelSize(

                       R.styleable.ViewGroup_MarginLayout_layout_marginBottom,

                        DEFAULT_MARGIN_RESOLVED);

 

                startMargin = a.getDimensionPixelSize(

                       R.styleable.ViewGroup_MarginLayout_layout_marginStart,

                        DEFAULT_MARGIN_RELATIVE);

               endMargin = a.getDimensionPixelSize(

                       R.styleable.ViewGroup_MarginLayout_layout_marginEnd,

                        DEFAULT_MARGIN_RELATIVE);

 

                if (isMarginRelative()) {

                   mMarginFlags |=NEED_RESOLUTION_MASK;

                }

           }

 

           final boolean hasRtlSupport =c.getApplicationInfo().hasRtlSupport();

           final int targetSdkVersion = c.getApplicationInfo().targetSdkVersion;

           if(targetSdkVersion <JELLY_BEAN_MR1|| !hasRtlSupport) {

                mMarginFlags |=RTL_COMPATIBILITY_MODE_MASK;

           }

 

           // Layout direction is LTR by default

           mMarginFlags|= LAYOUT_DIRECTION_LTR;

 

           a.recycle();

       }

 

       /**

        * {@inheritDoc}

        */

       publicMarginLayoutParams(intwidth,intheight) {

           super(width,height);

 

           mMarginFlags|= LEFT_MARGIN_UNDEFINED_MASK;

           mMarginFlags|= RIGHT_MARGIN_UNDEFINED_MASK;

 

           mMarginFlags&= ~NEED_RESOLUTION_MASK;

           mMarginFlags&= ~RTL_COMPATIBILITY_MODE_MASK;

       }

 

       /**

        * Copy constructor. Clones the width, height and margin values of thesource.

        *

        * @param source The layout params to copy from.

        */

       

       /*

        * 复制构造器,克隆源 MarginLayoutParams的宽高值和外边距值

        */

       publicMarginLayoutParams(MarginLayoutParams source) {

           this.width = source.width;

           this.height = source.height;

 

           this.leftMargin = source.leftMargin;

           this.topMargin = source.topMargin;

           this.rightMargin = source.rightMargin;

           this.bottomMargin = source.bottomMargin;

           this.startMargin = source.startMargin;

           this.endMargin = source.endMargin;

 

           this.mMarginFlags = source.mMarginFlags;

       }

 

       /**

        * {@inheritDoc}

        */

       publicMarginLayoutParams(LayoutParams source) {

           super(source);

 

           mMarginFlags|= LEFT_MARGIN_UNDEFINED_MASK;

           mMarginFlags|= RIGHT_MARGIN_UNDEFINED_MASK;

 

           mMarginFlags&= ~NEED_RESOLUTION_MASK;

           mMarginFlags&= ~RTL_COMPATIBILITY_MODE_MASK;

       }

 

       /**

        * Sets the margins, in pixels. A call to{@link android.view.View#requestLayout()} needs

        * to be done so that the new margins are taken into account. Left andright margins may be

        * overriden by {@linkandroid.view.View#requestLayout()} depending onlayout direction.

        *

        * @param left the left margin size

        * @param top the top margin size

        * @param right the right margin size

        * @param bottom the bottom margin size

        *

        * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginLeft

        * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginTop

        * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginRight

        * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginBottom

        */

       

       /*

        * 设置所有外边距,需要调用android.view.View#requestLayout()方法后新的外边距才会被考虑进去

        * 左右外边距可能被android.view.View#requestLayout()重写,这要依赖于布局方向

        */

       public void setMargins(int left,int top, int right,int bottom) {

           leftMargin= left;

           topMargin= top;

           rightMargin= right;

           bottomMargin= bottom;

           mMarginFlags&= ~LEFT_MARGIN_UNDEFINED_MASK;

           mMarginFlags&= ~RIGHT_MARGIN_UNDEFINED_MASK;

           if(isMarginRelative()) {

                mMarginFlags |=NEED_RESOLUTION_MASK;

           } else{

                mMarginFlags &= ~NEED_RESOLUTION_MASK;

           }

       }

 

       /**

        * Sets the relative margins, in pixels. A call to{@link android.view.View#requestLayout()}

        * needs to be done so that the new relative margins are taken intoaccount. Left and right

        * margins may be overriden by{@linkandroid.view.View#requestLayout()} depending onlayout

        * direction.

        *

        * @param start the start margin size

        * @param top the top margin size

        * @param end the right margin size

        * @param bottom the bottom margin size

        *

        * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart

        * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginTop

        * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd

        * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginBottom

        *

        * @hide

        */

       

       /*

        * 设置相对外边距,需要调用android.view.View#requestLayout()方法后新的外边距才会被考虑进去

        * 左右外边距可能被android.view.View#requestLayout()重写,这要依赖于布局方向

        */

       public void setMarginsRelative(int start,int top, int end,int bottom) {

           startMargin= start;

           topMargin= top;

           endMargin= end;

           bottomMargin= bottom;

           mMarginFlags|= NEED_RESOLUTION_MASK;

       }

 

       /**

        * Sets the relative start margin.

        *

        * @param start the start margin size

        *

        * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart

        */

       

       /* 设置起始外边距

        * @param start

        */

       public void setMarginStart(int start) {

           startMargin= start;

           mMarginFlags|= NEED_RESOLUTION_MASK;

       }

 

       /**

        * Returns the start margin in pixels.

        *

        * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart

        *

        * @return the start margin in pixels.

        */

       

       /* 获取起始外边距的值

        * @return

        */

       public int getMarginStart() {

           if(startMargin !=DEFAULT_MARGIN_RELATIVE) returnstartMargin;

           if((mMarginFlags &NEED_RESOLUTION_MASK) == NEED_RESOLUTION_MASK) {

                doResolveMargins();

           }

           switch(mMarginFlags &LAYOUT_DIRECTION_MASK) {

                case View.LAYOUT_DIRECTION_RTL:

                    returnrightMargin;

                case View.LAYOUT_DIRECTION_LTR:

               default:

                    returnleftMargin;

           }

       }

 

       /**

        * Sets the relative end margin.

        *

        * @param end the end margin size

        *

        * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd

        */

       

       /* 设置末尾外边距

        * @param end

        */

       public void setMarginEnd(int end) {

           endMargin= end;

           mMarginFlags|= NEED_RESOLUTION_MASK;

       }

 

       /**

        * Returns the end margin in pixels.

        *

        * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd

        *

        * @return the end margin in pixels.

        */

       public int getMarginEnd() {

           if(endMargin !=DEFAULT_MARGIN_RELATIVE) returnendMargin;

           if((mMarginFlags &NEED_RESOLUTION_MASK) == NEED_RESOLUTION_MASK) {

                doResolveMargins();

           }

           switch(mMarginFlags &LAYOUT_DIRECTION_MASK) {

                case View.LAYOUT_DIRECTION_RTL:

                    returnleftMargin;

                case View.LAYOUT_DIRECTION_LTR:

                default:

                    returnrightMargin;

           }

       }

 

       /**

        * Check if margins are relative.

        *

        * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart

        * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd

        *

        * @return true if either marginStart or marginEnd has been set.

        */

       

       /* 检查外边距是否是相对的(是否被设置)

        * @return 如果marginStart或marginEnd被设置,返回true,被设置成默认值DEFAULT_MARGIN_RELATIVE也会返回true

        */

       public boolean isMarginRelative() {

           return(startMargin !=DEFAULT_MARGIN_RELATIVE || endMargin != DEFAULT_MARGIN_RELATIVE);

       }

 

       /**

        * Set the layout direction

        * @param layoutDirection the layout direction.

        *        Should be either {@link View#LAYOUT_DIRECTION_LTR}

        *                     or {@link View#LAYOUT_DIRECTION_RTL}.

        */

       

       /* 设置布局方向

        * @param layoutDirection

        */

       public void setLayoutDirection(int layoutDirection) {

           if(layoutDirection != View.LAYOUT_DIRECTION_LTR &&

                    layoutDirection !=View.LAYOUT_DIRECTION_RTL) return;

           if(layoutDirection != (mMarginFlags&LAYOUT_DIRECTION_MASK)){

                mMarginFlags &= ~LAYOUT_DIRECTION_MASK;

                mMarginFlags |= (layoutDirection &LAYOUT_DIRECTION_MASK);

                if (isMarginRelative()) {

                    mMarginFlags |=NEED_RESOLUTION_MASK;

                } else {

                    mMarginFlags &= ~NEED_RESOLUTION_MASK;

                }

           }

       }

 

       /**

        * Retuns the layout direction. Can be either{@link View#LAYOUT_DIRECTION_LTR} or

        * {@link View#LAYOUT_DIRECTION_RTL}.

        *

        * @return the layout direction.

        */

       

       /* 返回布局方向对应的值 =标记值

        * @return

        */

       public int getLayoutDirection() {

           return(mMarginFlags &LAYOUT_DIRECTION_MASK);

       }

 

       /**

        * This will be called by {@linkandroid.view.View#requestLayout()}. Left andRight margins

        * may be overridden depending on layout direction.

        */

       @Override

       public void resolveLayoutDirection(int layoutDirection) {

           setLayoutDirection(layoutDirection);

 

           // No relative margin or pre JB-MR1 case orno need to resolve, just dont do anything

           // Will use the left and right margins ifno relative margin is defined.

           if(!isMarginRelative() ||

                    (mMarginFlags &NEED_RESOLUTION_MASK) != NEED_RESOLUTION_MASK)return;

 

           // Proceed with resolution

           doResolveMargins();

       }

 

       private void doResolveMargins() {

           if ((mMarginFlags &RTL_COMPATIBILITY_MODE_MASK) == RTL_COMPATIBILITY_MODE_MASK) {

                // if left or right margins are not defined and if we have some start orend margin

                // defined then use those start and end margins.

               if ((mMarginFlags&LEFT_MARGIN_UNDEFINED_MASK)== LEFT_MARGIN_UNDEFINED_MASK

                        && startMargin >DEFAULT_MARGIN_RELATIVE) {

                    leftMargin =startMargin;

                }

                if ((mMarginFlags&RIGHT_MARGIN_UNDEFINED_MASK)== RIGHT_MARGIN_UNDEFINED_MASK

                        && endMargin >DEFAULT_MARGIN_RELATIVE) {

                    rightMargin =endMargin;

                }

           } else{

                // We have some relative margins (either the start one or the end one orboth). So use

                // them and override what has been defined for left and right margins. Ifeither start

                // or end margin is not defined, just set it to default "0".

                switch(mMarginFlags&LAYOUT_DIRECTION_MASK){

                    case View.LAYOUT_DIRECTION_RTL:

                        leftMargin = (endMargin>DEFAULT_MARGIN_RELATIVE)?

                                endMargin :DEFAULT_MARGIN_RESOLVED;

                        rightMargin = (startMargin>DEFAULT_MARGIN_RELATIVE)?

                                startMargin :DEFAULT_MARGIN_RESOLVED;

                        break;

                   case View.LAYOUT_DIRECTION_LTR:

                    default:

                        leftMargin = (startMargin>DEFAULT_MARGIN_RELATIVE)?

                                startMargin :DEFAULT_MARGIN_RESOLVED;

                        rightMargin = (endMargin>DEFAULT_MARGIN_RELATIVE)?

                                endMargin :DEFAULT_MARGIN_RESOLVED;

                        break;

                }

           }

           mMarginFlags&= ~NEED_RESOLUTION_MASK;

       }

 

       /**

        * @hide

        */

       public boolean isLayoutRtl() {

           return((mMarginFlags &LAYOUT_DIRECTION_MASK) ==View.LAYOUT_DIRECTION_RTL);

       }

 

       /**

        * @hide

        */

       @Override

       public void onDebugDraw(View view, Canvas canvas, Paintpaint) {

           Insets oi = isLayoutModeOptical(view.mParent) ? view.getOpticalInsets(): Insets.NONE;

 

           fillDifference(canvas,

                    view.getLeft()   + oi.left,

                    view.getTop()    + oi.top,

                    view.getRight()  - oi.right,

                    view.getBottom() -oi.bottom,

                    leftMargin,

                    topMargin,

                    rightMargin,

                   bottomMargin,

                    paint);

       }

    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值