如何使用Android XML形状画一个圆内嵌圆?

50

我正在尝试为我的应用程序制作一个进度条的拇指,我希望有一个内部圆环被不同的、更大的(半透明的)外部圆环所包围。我正在尝试使用layer-list,但我遇到了问题。以下是我的代码...

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
    <shape
        android:shape="oval" >
        <solid android:color="#00f" />

        <size
            android:height="15dp"
            android:width="15dp" />
    </shape>
</item>

<item>
    <shape
        android:shape="oval" >
        <solid android:color="#f00" />

        <size
            android:height="10dp"
            android:width="10dp" />
    </shape>
</item>

</layer-list>

我期望能够看到一个小红圆圈在一个大蓝圆圈的上方,但是我只看到了小红圆圈。有人有任何想法吗?


1
你可能想画一个环形而不是椭圆形? - Stan
我想要的是类似于Google Play音乐应用程序使用的seekbar...它们在中间有一个橙色圆圈,周围有一个透明的橙色圆圈。你有任何可以模仿这个的代码吗?我刚开始使用Android XML可绘制对象,所以对环形方法还不太熟悉。 - jas7457
你看过/尝试过这个吗?:http://stackoverflow.com/questions/4413652/nested-shapes-in-android-sdk - turbo
2
这只是使用layer-list,就像我正在做的一样。我注意到如果我在第二个项目上设置android:top="3dp" android:left="3dp",现在我看到两个圆圈。奇怪的是,即使我在上面的<size>属性中声明它们不同,它们两个都被设置为相同的高度和宽度。它们似乎都默认为较大的尺寸。 - jas7457
9个回答

88
我能完成这个任务。翻译如下:

我唯一成功的方法是定义一个透明描边来区别内部(即顶部)圆形和更大更小的圆形之间的差异。

例如,这样做:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Larger blue circle in back -->
<item>
    <shape android:shape="oval">
        <solid android:color="#00f"/>
        <size
                android:width="15dp"
                android:height="15dp"/>
    </shape>
</item>
<!-- Smaller red circle in front -->
<item>
    <shape android:shape="oval">
        <!-- transparent stroke = larger_circle_size - smaller_circle_size -->
        <stroke android:color="@android:color/transparent"
                android:width="5dp"/>
        <solid android:color="#f00"/>
        <size
                android:width="10dp"
                android:height="10dp"/>
    </shape>
</item>
</layer-list>

...看起来是这样的:

输入图片描述


2
圆形内部没有出现在中心...这需要在代码中进行修改吗...? - Abhishek
2
请注意,此解决方案会产生过度绘制,因为它在另一个实心圆上绘制了一个实心圆。您可以在开发者设置中检查是否存在过度绘制(调试GPU过度绘制->显示过度绘制区域)。您可以通过为较大的圆形设置一些<padding>来避免这种情况,这些圆形不应该是<solid>,而只有<stroke>。或者更好的方法是:如果您只需要2个圆,请使用一个带有内部<solid>和外部<stroke>的单个圆。 - Albert Vila Calvo

16

如果您需要画3个或更多的圆圈,请按照以下模式:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Larger blue circle -->
    <item>
        <shape android:shape="oval">
            <padding
                android:bottom="20dp"
                android:left="20dp"
                android:right="20dp"
                android:top="20dp" />
            <size
                android:width="100dp"
                android:height="100dp" />
            <stroke
                android:width="20dp"
                android:color="#0000ff" />
        </shape>
    </item>
    <!-- Green circle in middle -->
    <item>
        <shape android:shape="oval">
            <padding
                android:bottom="20dp"
                android:left="20dp"
                android:right="20dp"
                android:top="20dp" />
            <size
                android:width="100dp"
                android:height="100dp" />
            <stroke
                android:width="20dp"
                android:color="#00ff00" />
        </shape>
    </item>
    <!-- Smaller red circle at front -->
    <item>
        <shape android:shape="oval">
            <size
                android:width="100dp"
                android:height="100dp" />
            <solid android:color="#ff0000" />
        </shape>
    </item>
</layer-list>

结果:

结果:

在此输入图像描述

请注意,与其他答案不同,此解决方案不会在其他圆圈的上方绘制圆圈,这样可以避免过度绘制


谢谢。这很有帮助。我正在寻找三层圆形,一个在另一个内部。 - Trupti Nasit

13

虽然有些晚了,但也许会有所帮助。你可以使用 padding 来使圆形居中。

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
    <shape
        android:shape="oval">
        <solid
            android:color="#00fff"/>
        <padding
            android:bottom="30dp"
            android:left="30dp"
            android:right="30dp"
            android:top="30dp"/>
        <stroke
            android:width="1dp"
            android:color="@color/holo_red_light"/>
    </shape>
</item>
<item>
    <shape
        android:shape="oval">
        <solid
            android:color="#00666666"/>

        <size
            android:width="120dp"
            android:height="120dp"/>
        <stroke
            android:width="1dp"
            android:color="@color/holo_red_light"/>
    </shape>

</item>
</layer-list>

11

我在寻找如何画同心圆时,只找到了使用图层列表的方法,因此我将我的答案添加进来,仅使用shape。希望能对某些人有所帮助。

<shape android:shape="oval">
    <solid android:color="#FFF" />
    <size
        android:width="15dp"
        android:height="15dp" />
    <stroke
        android:width="6dp"
        android:color="#000" /> 
</shape>

这就是结果。 在此输入图像描述


简单而优雅的解决方案。 - Nizam

9

希望这可以帮到你。这是可绘制的*.xml文件。

    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

      <item>
          <shape android:shape="oval">
              <padding
                  android:bottom="1dp"
                  android:left="1dip"
                  android:right="1dp"
                  android:top="1dp" />

              <solid android:color="#000" />
          </shape>
      </item>
      <item>
          <shape android:shape="oval">
              <padding
                  android:bottom="1dp"
                  android:left="1dip"
                  android:right="1dp"
                  android:top="1dp" />

              <solid android:color="#EEE" />
          </shape>
      </item>
    </layer-list>

8
我通过在<layer-list>中设置<item>的宽度和高度解决了这个问题。虽然这可能不是最佳实践,但对于具有固定尺寸的列表视图图标背景来说似乎还可以。
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <!-- larger circle at the back -->
    <item android:height="54dp" android:width="54dp" android:gravity="center">
        <shape
               android:shape="oval">

            <solid
                android:color="#0000FF"/>

            <!-- thicker outer boarder -->
            <stroke
                android:width="2dp"
                android:color="#000000"/>
        </shape>
    </item>


    <!-- inner circle -->
    <item android:height="40dp" android:width="40dp" android:gravity="center">
        <shape
               android:shape="oval"  >
            <solid
                android:color="#00FF00"/>

            <stroke
                android:width="1dp"
                android:color="#000000"/>

        </shape>
    </item>
</layer-list>

3
对于形状,android:heightandroid:width需要API 23+版本。对于旧设备,请改用<size>标签。 - Testing Here

0

这是Sean Barbeau答案的简短版本

<stroke
    android:width="1dp"
    android:color="@color/white" />
<solid android:color="@color/dark_blue" />

<size
    android:width="14dp"
    android:height="14dp" />


0
希望以下代码片段能够帮到您 :)
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
        <!-- larger circle at the back -->
        <item>
            <shape xmlns:android="http://schemas.android.com/apk/res/android"
                   android:innerRadius="0dp"
                   android:shape="ring"
                   android:thicknessRatio="2"
                   android:useLevel="false" >
                  <solid android:color="#FFFFFF" />
                  <stroke
                      android:width="1dp"
                      android:color="#000000" /></shape>
        </item>

    <!-- inner circle -->
    <item  >
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
               android:innerRadius="0dp"
               android:shape="ring"
               android:thicknessRatio="2.1"
               android:useLevel="false" >
            <solid android:color="#000000" />
            <stroke
                android:width="1dp"
                android:color="#FFFFFF" /></shape>
    </item>
</layer-list>

0

你只需要使用 Shap 属性

xml 代码 drawable

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <stroke android:width="2dp" android:color="#B91969"/>
    <size android:width="@dimen/dim_16dp" android:height="@dimen/dim_16dp" />
    <solid android:color="#0f0" />
</shape>

输出

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接