How can I work around Android issue 9161, where bottomRightRadius and bottomLeftRadius are swapped?
我的目标:
图1:目标
所以,在我知道这个问题之前,这是我尝试过的方法。
首先,基本布局:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <LinearLayout android:orientation="horizontal" android:layout_below="@id/heading" android:layout_marginTop="10dp" android:layout_width="@dimen/horizontal_two_button_width" android:layout_height="@dimen/button_height_small"> <Button android:id="@+id/button_one" android:layout_width="0dp" android:layout_weight="1.0" android:layout_height="fill_parent" android:padding="10dp" style="@style/ButtonText" android:background="@drawable/button_left_green" /> <Button android:id="@+id/button_two" android:layout_width="0dp" android:layout_weight="1.0" android:layout_height="fill_parent" android:padding="10dp" style="@style/ButtonText" android:background="@drawable/button_right_green" /> </LinearLayout> |
" button_left_green"可绘制对象:
1 2 3 4 5 6 7 8 | <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/button_left_green_pressed" android:state_pressed="true" /> <item android:drawable="@drawable/button_left_green_focused" android:state_focused="true" /> <item android:drawable="@drawable/button_left_green_default" /> </selector> |
例如,可绘制的'button_left_green_default':
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape android:shape="rectangle"> <solid android:color="@color/shadow" /> <corners android:radius="5dp" android:topLeftRadius="5dp" android:topRightRadius="0dp" android:bottomLeftRadius="5dp" android:bottomRightRadius="0dp" /> </shape> </item> <item android:bottom="19dp" android:top="1dp" android:left="1dp" android:right="1dp"> <shape android:shape="rectangle"> <gradient android:startColor="@color/button_left_green_top_gradient_start" android:endColor="@color/button_left_green_top_gradient_end" android:angle="270" /> <corners android:radius="5dp" android:topLeftRadius="5dp" android:topRightRadius="0dp" android:bottomLeftRadius="0dp" android:bottomRightRadius="0dp" /> </shape> </item> <item android:top="19dp" android:bottom="1dp" android:left="1dp" android:right="1dp"> <shape android:shape="rectangle"> <solid android:color="@color/button_left_green_bottom_gradient" /> <corners android:radius="5dp" android:topLeftRadius="0dp" android:topRightRadius="0dp" android:bottomLeftRadius="5dp" android:bottomRightRadius="0dp" /> </shape> </item> </layer-list> |
因此,毕竟,我得到了图2中的图像:
图2:取一个
在仔细检查了下角的定义之后,我确信自己一直疯了,直到找到已知问题:http://code.google.com/p/android/issues/detail?id=9161 我宁愿不只是交换它们,因为如果/在问题解决后,按钮将在较新的版本中损坏。 我的一个想法是将实际按钮保留为常规矩形(即无角半径),然后将两个按钮都用圆角矩形包裹。我向具有圆角的LinearLayout添加了一个可绘制背景,但是按钮的角与LinearLayout圆角的边缘重叠(请参见图3)。 如何使按钮的背景保持在其父级背景可绘制范围之内?或者您对解决该错误还有其他建议吗? 另一种解决方案是创建另一个名为" drawable-v12 "的文件夹。 在此处输入正确的半径(因此,bottomLeftRadius,topLeftRadius),并在原始可绘制文件夹中输入交换的值。然后3.1将使用v12文件夹,而3.1之前的版本将使用drawable文件夹。 这感觉像是一种hack,但确实有效。 这些按钮最初由(1)一个外部阴影,(2)一个上半渐变和(3)一个底部纯色组成。这是我的工作: 这是左按钮正常状态下XML的示例。 但是,我确实失去了上半部分的渐变色,但是我可以忍受两个音调的按钮。结果如下所示: 更好的解决方案: 在分配拐角半径时使用尺寸值,而不是在可绘制对象中对其进行硬编码。加载3.1之前的版本时,它将使用文件夹 下使用正确的拐角半径值。
图3:取两个
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Main part of button -->
<item
android:bottom="20dp"
android:right="5dp">
<shape android:shape="rectangle">
<solid android:color="@color/button_normal_green_top" />
<corners android:radius="5dp" />
</shape>
</item>
<item
android:top="20dp"
android:right="5dp">
<shape
android:shape="rectangle">
<solid android:color="@color/button_normal_green_bottom" />
<corners android:radius="5dp" />
</shape>
</item>
<!-- Patch left middle part of button, which was left empty due to rounded
corners on top and bottom halves of button -->
<item
android:top="5dp"
android:bottom="20dp"
android:right="5dp">
<shape android:shape="rectangle">
<solid android:color="@color/button_normal_green_top" />
</shape>
</item>
<item
android:top="20dp"
android:bottom="5dp"
android:right="5dp">
<shape
android:shape="rectangle">
<solid android:color="@color/button_normal_green_bottom" />
</shape>
</item>
<!-- Patch right middle and make right side corners square -->
<item
android:bottom="20dp"
android:left="15dp">
<shape android:shape="rectangle">
<solid android:color="@color/button_normal_green_top" />
</shape>
</item>
<item
android:top="20dp"
android:left="15dp">
<shape android:shape="rectangle">
<solid android:color="@color/button_normal_green_bottom" />
</shape>
</item>
</layer-list>
右下角半径。
为什么这样更好?您不需要重复可绘制的代码。现在,您可以更改任何与拐角半径无关的代码,而不必更新2个或更多位置。
此问题似乎已在Android 3.0中修复。关于该问题的评论解释了如何具有向后兼容性。
如果我们提供已经左右互换的配置,它应该可以工作;以便错误交换将恢复所需的配置,如下所示,仅适用于左侧弯曲的且带有尖锐边缘的按钮
1 2 3 | <corners android:radius="2dp" android:topLeftRadius="2dp" android:topRightRadius="0dp" android:bottomLeftRadius="0dp" android:bottomRightRadius="2dp"> |