22

问题

我有一个自定义的 Android 视图,我希望用户在其中设置重力以便在onDraw. 这是我正在使用的简化版本onDraw

// check gravity
if ((mGravity & Gravity.CENTER_VERTICAL) == Gravity.CENTER_VERTICAL) {
    // draw the content centered vertically
} else if ((mGravity & Gravity.BOTTOM) == Gravity.BOTTOM) {
    // draw the content at the bottom
}

wheremGravity是从 xml 属性中获得的(像这样)。

如果我将重力设置为Gravity.CENTER_VERTICAL它工作正常。但我惊讶地发现,如果我将它设置为Gravity.BOTTOMGravity.CENTER_VERTICAL检查仍然是真的!

为什么会这样?

我不得不查看二进制值以了解原因:

因此,当我这样做时

mGravity = Gravity.BOTTOM;
(mGravity & Gravity.CENTER_VERTICAL) == Gravity.CENTER_VERTICAL
//  (0101 & 0001) == 0001

我得到一个误报。

我该怎么办?

那么我应该如何检查重力标志呢?

我可以做类似的事情if (mGravity == Gravity.CENTER_VERTICAL),但我只会得到完全匹配。如果用户将重力设置为类似的东西,center_vertical|right那么它将失败。

4

2 回答 2

23

你可以检查FrameLayout它的孩子是如何生的。特别是,这段代码:

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:
        ...
    case Gravity.RIGHT:
        ...
    case Gravity.LEFT:
        ...
}

switch (verticalGravity) {
    case Gravity.TOP:
        ...
    case Gravity.CENTER_VERTICAL:
        ...
    case Gravity.BOTTOM:
        ...
}

课堂上有面具GravityVERTICAL_GRAVITY_MASKHORIZONTAL_GRAVITY_MASK这将帮助您找出应用了哪些重力。

于 2017-02-18T10:49:51.450 回答
11

这是对@azizbekian 非常有用的解决方案的补充答案。我添加它是为了帮助自己更全面地了解重力在幕后是如何工作的。

水平轴重力

LEFT并且RIGHT被称为绝对重力。也就是说,如果用户指定START或的相对重力END,则根据情况在内部将其转换为绝对重力RIGHT或。LEFT

0000 0001  CENTER_HORIZONTAL
0000 0011  LEFT
0000 0101  RIGHT
---------  
0000 0111  HORIZONTAL_GRAVITY_MASK

关于START和的注释END

1000 0000 0000 0000 0000 0011  START
0000 0000 0000 0000 0000 0011  LEFT
1000 0000 0000 0000 0000 0101  END
0000 0000 0000 0000 0000 0101  RIGHT
-----------------------------
0000 0000 0000 0000 0000 0111  HORIZONTAL_GRAVITY_MASK

正如您在此处看到的,STARTLEFT相差一点点。END对于和也是一样的RIGHT。因此,如果您HORIZONTAL_GRAVITY_MASK直接使用STARTand END,它们将分别默认为LEFTand RIGHT。但是,应谨慎使用。应考虑从右到左的语言区域设置。

垂直轴重力

y 轴重力从 x 轴(水平)重力移动了 4 位。

0001 0000  CENTER_VERTICAL
0011 0000  TOP
0101 0000  BOTTOM
---------
0111 0000  VERTICAL_GRAVITY_MASK

两个轴

请注意,这CENTERCENTER_VERTICAL和的组合CENTER_HORIZONTAL。因此,您也可以使用其中一种重力蒙版进行转换。

0000 0001  CENTER_HORIZONTAL
0001 0000  CENTER_VERTICAL
0001 0001  CENTER
---------
0000 0111  HORIZONTAL_GRAVITY_MASK
0111 0000  VERTICAL_GRAVITY_MASK

位数学

使用位 OR 运算符 ( |) 组合水平和垂直重力。

例子:

int myGravity = Gravity.RIGHT | Gravity.BOTTOM;

0000 0101  RIGHT
0101 0000  BOTTOM
---------
0101 0101  myGravity

将位与运算符 ( &) 与其中一个重力掩码一起使用以隔离水平或垂直重力。

例子

int verticalGravity = myGravity & Gravity.VERTICAL_GRAVITY_MASK;
if (verticalGravity == Gravity.BOTTOM) ...

0101 0101  myGravity
0111 0000  VERTICAL_GRAVITY_MASK
---------
0101 0000  verticalGravity
0101 0000  BOTTOM
于 2017-02-20T06:40:26.883 回答