详解安卓Gravity的进制封装

详解安卓Gravity的进制封装

前言

安卓中的部分控件中有一个setGravity的方法,可以使用它设置View内重力的方向。

以LinearLayout为例,它的使用是这样的

LinearLayout linearlayout=findViewById(R.id.xxx);
linearlayout.setGravity(Gravity.Top|Gravity.Center|Gravity.Start);//添加重力

这样的代码,通过符号"|"设置多种重力仅需要一次set,阅读起来十分简洁。

那它是怎么做到的呢?

准备

代码分析需要一定的进制操作符基础,我们先简单复习一下java关于进制的运算符

声明:以下均是对2进制的操作

定义A=0011_1100

定义B=0000_1101

操作符描述例子
&如果都是1,则为1,否则0A&B=0000_1100
|如果都是0,则为0,否则1A|B=0011_1101
^如果值相同,则为0,否则1A^B=0011_0001
~如果是0,则变1.如果是1,则变0~A=1100_0011
<<向左移动,用0补齐A<<2=1111_0000
>>向右移动A>>2=1111
>>>向右移动,用0补齐A>>>2=0000_1111

代码分析

复习好了进制运算符,我们来看一下代码

按下Ctrl+左键,单击进入setGravity方法可以看到如下代码

  public void setGravity(int gravity) {
        if (mGravity != gravity) {
            if ((gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
                gravity |= Gravity.START;
            }

            if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
                gravity |= Gravity.TOP;
            }

            mGravity = gravity;
            //去除了部分无关代码
        }
    }

可以确定mGravity是LinearLayout的重力储存变量

我们再来分析一下这两个if是干什么的。按下Ctrl+左键,跟进Gravity

内部定义的常量如下

//去除了部分无关代码
public static final int AXIS_SPECIFIED = 0x0001;//1
public static final int AXIS_PULL_BEFORE = 0x0002;//10
public static final int AXIS_PULL_AFTER = 0x0004;//100
public static final int AXIS_X_SHIFT = 0;
public static final int AXIS_Y_SHIFT = 4;
public static final int TOP = (AXIS_PULL_BEFORE|AXIS_SPECIFIED)<<AXIS_Y_SHIFT;//110000
public static final int BOTTOM = (AXIS_PULL_AFTER|AXIS_SPECIFIED)<<AXIS_Y_SHIFT;//1010000
public static final int LEFT = (AXIS_PULL_BEFORE|AXIS_SPECIFIED)<<AXIS_X_SHIFT;//11
public static final int RIGHT = (AXIS_PULL_AFTER|AXIS_SPECIFIED)<<AXIS_X_SHIFT;//101
public static final int RELATIVE_LAYOUT_DIRECTION = 0x00800000;//100000000000000000000000
public static final int START = RELATIVE_LAYOUT_DIRECTION | LEFT;
//100000000000000000000011
public static final int END = RELATIVE_LAYOUT_DIRECTION | RIGHT;
//100000000000000000000101
public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = START | END;
//100000000000000000000111
//为了方便阅读我将这些常量的二进制写在了注释

观察代码

TOPBOTTOM都是左偏移4位的值,而LEFTRIGHT都是左偏移0位的值

再根据变量名称,可以确定 将Gravity从后向前看,前四位控制的是与X轴有关的重力,四位以后控制的是与Y轴有关的重力

STARTEndLEFTRIGHT补位后的值

RELATIVE_HORIZONTAL_GRAVITY_MASKSTART|END

回过来再看刚才的if

if ((gravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
                gravity |= Gravity.START;
            }

很明显,这个if是判断传入的gravity是否具有LEFT或者RIGHT的重力方向,也就是X轴的重力方向

如果不具备X轴的重力,则添加START

第2个if则是判断是否具备Y轴的重力

至此,setGravity就分析完成了

那怎么判断传入的gravity是否具有某一方向的重力呢

if(gravity&BOTTOM^BOTTOM==0){
    //有
}

总结

对于多类型参数传参操作,可以使用进制封装进行大幅度简化

我们只需要定义每一位的作用,并遵循一个规则

1为有

0为没有

|添加

^如果没有就添加,如果有就去除

&判断是否有
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有头发的琦玉

打点钱,我会再努力的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值