博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android:layout_gravity 和 android:gravity 的区别
阅读量:4029 次
发布时间:2019-05-24

本文共 5354 字,大约阅读时间需要 17 分钟。

Android开发必遇问题,最有可能忘记两者之间的区别的问题之一

如下是Google搜索出来的结果
这里写图片描述

记忆方法

联想/形像記法

* 利用成员变量的属性记录,gravity是类的成员变量,自然就是控制子节点的排版效果,设置自己内部的排版重心,即排版内部子类的参数。排版它人的重心(主动)
* layout_gravity的前缀有layout,即属于LayoutParams类的属性值,然后LayoutParams是给父view用的,即 layout_gravity是设置自己在父view的排版重点,即被排版时的参数!被它人排版的重心(被动)

文档说明

android:gravity

这里写图片描述

关键字 should position , 主动

android:layout_gravity

这里写图片描述

关键字 should be placed, 被动

源码左证

如下是LinearLayout的onLayout函数中可以看到两个参数的使用情况

void layoutVertical(int left, int top, int right, int bottom) {        final int paddingLeft = mPaddingLeft;        int childTop;        int childLeft;        // Where right end of child should go        final int width = right - left;        int childRight = width - mPaddingRight;        // Space available for child        int childSpace = width - paddingLeft - mPaddingRight;        final int count = getVirtualChildCount();        final int majorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;        final int minorGravity = mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;        // 使用mGravity来计算第一个子view的top        switch (majorGravity) {           case Gravity.BOTTOM:               // mTotalLength contains the padding already               childTop = mPaddingTop + bottom - top - mTotalLength;               break;               // mTotalLength contains the padding already           case Gravity.CENTER_VERTICAL:               childTop = mPaddingTop + (bottom - top - mTotalLength) / 2;               break;           case Gravity.TOP:           default:               childTop = mPaddingTop;               break;        }        for (int i = 0; i < count; i++) {            final View child = getVirtualChildAt(i);            if (child == null) {                childTop += measureNullChild(i);            } else if (child.getVisibility() != GONE) {                final int childWidth = child.getMeasuredWidth();                final int childHeight = child.getMeasuredHeight();                //在排子view时才使用到子view的LayoutParams中的gravity                final LinearLayout.LayoutParams lp =                        (LinearLayout.LayoutParams) child.getLayoutParams();                int gravity = lp.gravity;                if (gravity < 0) {                    gravity = minorGravity;                }

相关补充

  1. ViewGroup是个抽象类,子类继承它时需要Override OnLayout方法
  2. LinearLayout、RelativeLayout等ViewGroup子类就分别实现了自己的排版算法(Override OnLayout方法)
  3. ViewGroup子类们在排版过程中使用到gravity与layout_gravity等参数来排版子view(内容),值得注意的是mGravity不是ViewGroup的成员变量,另外各子类的排版策略是不一样的,所以gravity不是必须存在的与使用的,如FrameLayout
    如下是FrameLayout的OnLayout方法的代码
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        layoutChildren(left, top, right, bottom, false /* no force left gravity */);    }    void layoutChildren(int left, int top, int right, int bottom,                                  boolean forceLeftGravity) {        final int count = getChildCount();        final int parentLeft = getPaddingLeftWithForeground();        final int parentRight = right - left - getPaddingRightWithForeground();        final int parentTop = getPaddingTopWithForeground();        final int parentBottom = bottom - top - getPaddingBottomWithForeground();        for (int i = 0; i < count; i++) {            final View child = getChildAt(i);            if (child.getVisibility() != GONE) {                final LayoutParams lp = (LayoutParams) child.getLayoutParams();                final int width = child.getMeasuredWidth();                final int height = child.getMeasuredHeight();                int childLeft;                int childTop;                int gravity = lp.gravity;                if (gravity == -1) {                    gravity = DEFAULT_CHILD_GRAVITY;                }                final int layoutDirection = getLayoutDirection();                final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);                final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;                switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {                    case Gravity.CENTER_HORIZONTAL:                        childLeft = parentLeft + (parentRight - parentLeft - width) / 2 +                        lp.leftMargin - lp.rightMargin;                        break;                    case Gravity.RIGHT:                        if (!forceLeftGravity) {                            childLeft = parentRight - width - lp.rightMargin;                            break;                        }                    case Gravity.LEFT:                    default:                        childLeft = parentLeft + lp.leftMargin;                }                switch (verticalGravity) {                    case Gravity.TOP:                        childTop = parentTop + lp.topMargin;                        break;                    case Gravity.CENTER_VERTICAL:                        childTop = parentTop + (parentBottom - parentTop - height) / 2 +                        lp.topMargin - lp.bottomMargin;                        break;                    case Gravity.BOTTOM:                        childTop = parentBottom - height - lp.bottomMargin;                        break;                    default:                        childTop = parentTop + lp.topMargin;                }                child.layout(childLeft, childTop, childLeft + width, childTop + height);            }        }    }
你可能感兴趣的文章
Preprocessing data-sklearn数据预处理
查看>>
Java实现Oracle到MySQL的表迁移
查看>>
子类A继承父类B, A a = new A(); 则父类B构造函数、父类B静态代码块、父类B非静态代码块、子类A构造函数、子类A静态代码块、子类A非静态代码块 执行的先后顺序是?
查看>>
android:style和theme
查看>>
wait()、notify()和notifyAll()、sleep()、Condition、await()、signal()
查看>>
Arrays.asList()
查看>>
Big Endian 和 Little Endian
查看>>
java中重写方法应遵循规则
查看>>
Comparable的使用(用于Arrays.sort)
查看>>
Comparator(用于Arrays.sort)
查看>>
对自己的计划
查看>>
反应c语言程序结构特点的程序
查看>>
Android错误总结
查看>>
android margin
查看>>
Drawable setBounds()中的rect
查看>>
markdown编辑器
查看>>
过拟合原因及解决
查看>>
支持向量机(SVM)初探
查看>>
决策树与随机森林初探
查看>>
相似度与距离算法种类总结
查看>>