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

时间:2017-02-11 09:05:58

标签: java android android-layout flags android-gravity

问题

我有一个自定义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
}

其中mGravity是从xml属性(like this)获得的。

如果我将重力设置为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的内容,则会失败。

2 个答案:

答案 0 :(得分:16)

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

Gravity课程中有VERTICAL_GRAVITY_MASK HORIZONTAL_GRAVITY_MASKv-for="(index, pet) in pets" ,这将帮助您了解已应用的重力。

答案 1 :(得分:4)

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

水平轴重力

LEFTRIGHT被称为绝对引力。也就是说,如果用户指定STARTEND的相对重力,则converted internally的绝对重力为RIGHTLEFT,具体取决于情况。

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

正如您在此处所见,STARTLEFT仅相差一位。 ENDRIGHT也是如此。因此,如果您直接在HORIZONTAL_GRAVITY_MASKSTART上使用END,则默认分别为LEFTRIGHT。但是,应谨慎使用。应该考虑从右到左的语言区域。

垂直轴重力

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

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

实施例

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