必威体育Betway必威体育官网
当前位置:首页 > IT技术

android:layout_gravity 和 android:gravity 的区别

时间:2019-10-10 19:14:34来源:IT技术作者:seo实验室小编阅读:58次「手机版」
 

layout_gravity

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);
            }
        }
    }

相关阅读

android线程管理五(ActivityThread与ApplicationThread

前言 android中App第一次启动时,会创建一个进程,在这个进程中可以启动各个组件(如Activity、BroadcastReceiver、Service),这些组件都

一文读懂 android 事件分发机制 MotionEvent

点击事件用MotionEvent表示,最重要的事件分别是: 手指按下:ACTION_DOWN 手指移动:ACTION_MOVE 手指抬起:ACTION_UP 点击事件的分发始

Android入门教程二十五之Button(按钮)与ImageButton(

今天给大家介绍的Android基本控件中的两个按钮控件,Button普通按钮和ImageButton图像按钮; 其实ImageButton和Button的用法基本类似

Android主线程(ActivityThread)源代码分析

在写这篇博客之前,先抛出一个问题,安卓应用程序的入口是什么呢?我想不少人可能回答说:application的onCreate方法,其实并不是的,即使

android 英语词库

android 英语词库(未完待续) drawable英 ['drɔ:əbl] 美 ['drɔəbl]adj.可曳的,可拉的; Compound英 [ˈkɒmpaʊnd] 美 [

分享到:

栏目导航

推荐阅读

热门阅读