如何在自定义 Android 视图中检查重力标志?
Posted
技术标签:
【中文标题】如何在自定义 Android 视图中检查重力标志?【英文标题】:How to check gravity flags in a custom Android View? 【发布时间】:2017-06-29 16:06:55 【问题描述】:问题
我有一个自定义的 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.BOTTOM
,Gravity.CENTER_VERTICAL
的检查仍然是真的!
为什么会这样?
我必须查看二进制值才能了解原因:
二进制:0001 0000
,Gravity.CENTER_VERTICAL
:常量值:16 (0x00000010)
二进制:0101 0000
,Gravity.BOTTOM
:常量值:80 (0x00000050)
因此,当我这样做时
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:
...
Gravity
类中有掩码:VERTICAL_GRAVITY_MASK
、HORIZONTAL_GRAVITY_MASK
,这将帮助您找出应用了哪些重力。
【讨论】:
我完成了这个测试,我可以确认它有效。我错过了VERTICAL_GRAVITY_MASK
。【参考方案2】:
这是对@azizbekian 非常有用的解决方案的补充答案。我添加它是为了帮助自己更全面地了解重力在幕后的工作原理。
横轴重力
LEFT
和 RIGHT
被称为绝对重力。也就是说,如果用户指定START
或END
的相对重力,则根据情况,它是converted internally 到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
正如您在此处看到的,START
和 LEFT
仅相差一位。 END
和 RIGHT
也是如此。因此,如果您直接在START
和END
上使用HORIZONTAL_GRAVITY_MASK
,它们将分别默认为LEFT
和RIGHT
。但是,应谨慎使用。应考虑从右到左的语言区域设置。
垂直轴重力
y 轴重力从 x 轴(水平)重力移动了 4 位。
0001 0000 CENTER_VERTICAL
0011 0000 TOP
0101 0000 BOTTOM
---------
0111 0000 VERTICAL_GRAVITY_MASK
两个轴
注意CENTER
是CENTER_VERTICAL
和CENTER_HORIZONTAL
的组合。因此,您也可以使用其中一种重力蒙版进行转换。
0000 0001 CENTER_HORIZONTAL
0001 0000 CENTER_VERTICAL
0001 0001 CENTER
---------
0000 0111 HORIZONTAL_GRAVITY_MASK
0111 0000 VERTICAL_GRAVITY_MASK
位数学
使用位或运算符 (|
) 组合水平和垂直重力。
例子:
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
【讨论】:
I'm adding this to help myself
, maan,这当然不仅适合你。不错,很详细!以上是关于如何在自定义 Android 视图中检查重力标志?的主要内容,如果未能解决你的问题,请参考以下文章
Android:在自定义视图上使用android绑定点击事件