关于圆角:我该如何解决交换了bottomRightRadius和bottomLeftRadius的Android问题9161?

 2021-04-27 

How can I work around Android issue 9161, where bottomRightRadius and bottomLeftRadius are swapped?

我的目标:

Figure

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中的图像:
Figure


另一种解决方案是创建另一个名为" drawable-v12 "的文件夹。

在此处输入正确的半径(因此,bottomLeftRadius,topLeftRadius),并在原始可绘制文件夹中输入交换的值。然后3.1将使用v12文件夹,而3.1之前的版本将使用drawable文件夹。


这感觉像是一种hack,但确实有效。

这些按钮最初由(1)一个外部阴影,(2)一个上半渐变和(3)一个底部纯色组成。这是我的工作:

  • 将上半部分和下半部分分别在四个角上倒圆。这在左侧和右侧的中间留有(1)个间隙,在右侧有(2)个圆角。
  • 创建了一个小矩形以填充左中间的间隙。
  • 创建了另一个小矩形,以填充右侧中间的间隙,并使右侧的上角和下角为正方形。
  • 这是左按钮正常状态下XML的示例。

    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    <?xml version="1.0" encoding="utf-8"?>
    <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>

    但是,我确实失去了上半部分的渐变色,但是我可以忍受两个音调的按钮。结果如下所示:
    Two


    更好的解决方案:

    • 创建另一个文件夹values-12
    • values-12下创建dimensions.xml文件。
    • values-12/dimensions.xml中将2维属性放在左下角,然后
      右下角半径。
    • values/dimensions.xml中将2维属性放入左下角和右下角的半径值,但请记住将其翻转。

    在分配拐角半径时使用尺寸值,而不是在可绘制对象中对其进行硬编码。加载3.1之前的版本时,它将使用文件夹values下的反转角半径值。加载3.1时,它将在文件夹values-12

    下使用正确的拐角半径值。

    为什么这样更好?您不需要重复可绘制的代码。现在,您可以更改任何与拐角半径无关的代码,而不必更新2个或更多位置。


    此问题似乎已在Android 3.0中修复。关于该问题的评论解释了如何具有向后兼容性。


    如果我们提供已经左右互换的配置,它应该可以工作;以便错误交换将恢复所需的配置,如下所示,仅适用于左侧弯曲的且带有尖锐边缘的按钮

    1
    2
    3
    <corners android:radius="2dp" android:topLeftRadius="2dp"
        android:topRightRadius="0dp" android:bottomLeftRadius="0dp"
        android:bottomRightRadius="2dp">