Sur*_*gch 17 java flags android android-layout 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
}
Run Code Online (Sandbox Code Playgroud)
其中mGravity从XML属性(获得这样).
如果我将引力设置为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
Run Code Online (Sandbox Code Playgroud)
我得到了误报.
我该怎么办?
那么我该怎么检查重力旗呢?
我可以做类似的事情if (mGravity == Gravity.CENTER_VERTICAL),但那时我只会得到完全匹配.如果用户将重力设置为类似的center_vertical|right那么它就会失败.
azi*_*ian 17
你可以检查一下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:
...
}
Run Code Online (Sandbox Code Playgroud)
还有就是口罩Gravity类:VERTICAL_GRAVITY_MASK,HORIZONTAL_GRAVITY_MASK这将帮助你找出已经被应用了哪些比重.
这是对@azizbekian非常有用的解决方案的补充回答。我添加此内容是为了帮助自己更充分地了解重力在幕后的工作方式。
LEFT并RIGHT称为绝对重力。即,如果用户指定START或的相对重力END,则根据情况将其在内部转换为RIGHT或的绝对重力LEFT。
0000 0001 CENTER_HORIZONTAL
0000 0011 LEFT
0000 0101 RIGHT
---------
0000 0111 HORIZONTAL_GRAVITY_MASK
Run Code Online (Sandbox Code Playgroud)
关于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
Run Code Online (Sandbox Code Playgroud)
如您在这里看到的,START并且LEFT只有一点点差异。END和和相同RIGHT。因此,如果HORIZONTAL_GRAVITY_MASK直接在START和上使用END,则它们分别默认为LEFT和RIGHT。但是,应谨慎使用。应考虑从右到左的语言环境。
y轴重力从x轴(水平)重力移了4位。
0001 0000 CENTER_VERTICAL
0011 0000 TOP
0101 0000 BOTTOM
---------
0111 0000 VERTICAL_GRAVITY_MASK
Run Code Online (Sandbox Code Playgroud)
请注意,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
Run Code Online (Sandbox Code Playgroud)
使用位OR运算符(|)组合水平和垂直重力。
例:
int myGravity = Gravity.RIGHT | Gravity.BOTTOM;
0000 0101 RIGHT
0101 0000 BOTTOM
---------
0101 0101 myGravity
Run Code Online (Sandbox Code Playgroud)
将位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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1753 次 |
| 最近记录: |