如何在自定义Android视图中检查重力标志?

问题

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

// 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
}

其中 是从 xml 属性中获取的(如下所示)。mGravity

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

为什么会发生这种情况?

我必须查看二进制值才能了解原因:

因此,当我这样做时

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

我收到误报。

我该怎么办?

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

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


答案 1

您可以检查 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


答案 2

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

水平轴重力

LEFT并被称为绝对重力。也就是说,如果用户指定相对重力为 或 ,则它在内部转换为绝对重力或取决于情况。RIGHTSTARTENDRIGHTLEFT

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

关于 和 的说明STARTEND

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

正如你在这里看到的,只有一点点不同。对于 和 是相同的。因此,如果直接使用 on 和 ,它们将分别默认为 和。但是,应谨慎使用。应考虑从右到左的语言区域设置。STARTLEFTENDRIGHTHORIZONTAL_GRAVITY_MASKSTARTENDLEFTRIGHT

垂直轴重力

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

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

两个轴

请注意,这是 和 的组合。因此,您也可以使用其中一个重力蒙版来转换它。CENTERCENTER_VERTICALCENTER_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

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

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

推荐