安卓中的圆形渐变

127

我正在尝试创建一个从屏幕中央向四周渐变的白色渐变,并在向边缘移动时变为黑色。

当我制作“普通”的渐变时,我一直在尝试不同的形状:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient android:startColor="#E9E9E9" android:endColor="#D4D4D4"
        android:angle="270"/>
</shape>

使用“椭圆形”时,我至少得到了一个圆形,但没有渐变效果。我该如何实现?

8个回答

268

你可以使用android:type="radial"来获取一个圆形渐变:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient android:type="radial" android:gradientRadius="250dp"
        android:startColor="#E9E9E9" android:endColor="#D4D4D4" />
</shape>

121
不仅起了作用,还解决了全球饥荒问题!谢谢! - pgsandstrom
2
附带说明:也可以在颜色中使用透明度字节。#ff00ff00 到 #7f0000ff 将从完全不透明的红色渐变为半透明的蓝色。 - Simon Forsberg
11
android:gradientRadius="250" 将被忽略。您应该指向一个具有px或dp值的dimen资源,例如:android:gradientRadius="@dimen/gradient_radius" - Bolling
4
谢谢Bolling,你说得对,android:gradientRadius="250"完全不起作用,我想在较旧的Android版本中它的行为可能会有所不同。 - Justin

156

我总是觉得在学习新概念时图像很有帮助,所以这是一个补充回答。

enter image description here

%p 表示父元素的百分比,也就是我们在可绘制视图上设置的最窄尺寸的百分比。上面的图片是通过在以下代码中更改 gradientRadius 生成的:

my_gradient_drawable

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:type="radial"
        android:gradientRadius="10%p"
        android:startColor="#f6ee19"
        android:endColor="#115ede" />
</shape>

可以像这样在视图的background属性上设置

<View
    android:layout_width="200dp"
    android:layout_height="100dp"
    android:background="@drawable/my_gradient_drawable"/>

中心

您可以使用以下方式更改半径的中心:

android:centerX="0.2"
android:centerY="0.7"

小数点是指相对于宽度和高度的分数,其中xy分别代表宽度和高度。

enter image description here

文档

以下是来自文档的一些注释,以更详细地解释事情。

 

android:gradientRadius

     

渐变半径,仅与径向渐变一起使用。可以是显式尺寸或相对于形状最小尺寸的分数值。

     

可能是浮点值,例如“1.2”。

     

可能是尺寸值,这是一个浮点数字,后面附加了单位,例如“14.5sp”。可用单位为:px(像素),dp(密度无关像素),sp(根据首选字体大小缩放像素),in(英寸)和mm(毫米)。

     

可能是分数值,这是一个浮点数,后面附加%或%p,例如“14.5%”。%后缀始终表示基准尺寸的百分比;可选的%p后缀提供相对于某些父容器的大小。


在Kikat中,当您从渐变半径中删除%p时,径向类型将起作用。对于Kikat android:gradientRadius="10" - mehmoodnisar125
在API 21中,您真的需要使用android:gradientRadius="10%p"(带有p)否则会出现异常。您还可以设置android:centerX="20%" - CoolMind
@CoolMind,您介意编辑答案并更新以反映这些更改吗?我现在正在使用Flutter做更多的事情,所以我没有及时更新我的Android答案。 - Suragch
@Suragch,感谢您提供详细的答案!我只想说您做得很好。并不是每个作者都能添加所有这些属性并描述它们的含义。 - CoolMind

5

如果您需要更多的控制,例如多种颜色和定位,您还可以在代码中完成它。以下是我用Kotlin创建可绘制径向渐变的片段:

object ShaderUtils {
    private class RadialShaderFactory(private val colors: IntArray, val positionX: Float,
                                      val positionY: Float, val size: Float): ShapeDrawable.ShaderFactory() {

        override fun resize(width: Int, height: Int): Shader {
            return RadialGradient(
                    width * positionX,
                    height * positionY,
                    minOf(width, height) * size,
                    colors,
                    null,
                    Shader.TileMode.CLAMP)
        }
    }

    fun radialGradientBackground(vararg colors: Int, positionX: Float = 0.5f, positionY: Float = 0.5f,
                                 size: Float = 1.0f): PaintDrawable {
        val radialGradientBackground = PaintDrawable()
        radialGradientBackground.shape = RectShape()
        radialGradientBackground.shaderFactory = RadialShaderFactory(colors, positionX, positionY, size)
        return radialGradientBackground
    }
}

基本用法(但可以使用其他参数进行调整):

view.background = ShaderUtils.radialGradientBackground(Color.TRANSPARENT, BLACK)

2

这是带有渐变、描边和圆形形状的完整xml代码。

<?xml version="1.0" encoding="utf-8"?>

<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >

    <!-- You can use gradient with below attributes-->
    <gradient
        android:angle="90"
        android:centerColor="#555994"
        android:endColor="#b5b6d2"
        android:startColor="#555994"
        android:type="linear" />

    <!-- You can omit below tag if you don't need stroke -->
   <stroke android:color="#3b91d7" android:width="5dp"/>

    <!-- Set the same value for both width and height to get a circular shape -->
    <size android:width="200dp" android:height="200dp"/>


    <!--if you need only a single color filled shape-->
    <solid android:color="#e42828"/>


</shape>

好的例子。谢谢。 - Sinan Ceylan

2
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:padding="10dp"
    android:shape="rectangle">

    <gradient
        android:endColor="@color/color1"
        android:gradientRadius="250dp"
        android:startColor="#8F15DA"
        android:type="radial" />

    <corners
        android:bottomLeftRadius="50dp"
        android:bottomRightRadius="50dp"
        android:radius="3dp"
        android:topLeftRadius="0dp"
        android:topRightRadius="50dp" />
</shape>

1

<gradient
    android:centerColor="#c1c1c1"
    android:endColor="#4f4f4f"
    android:gradientRadius="400"
    android:startColor="#c1c1c1"
    android:type="radial" >
</gradient>


1

我猜你应该添加android:centerColor

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
  android:startColor="#FFFFFF"
  android:centerColor="#000000"
  android:endColor="#FFFFFF"
  android:angle="0" />
</shape>

这个例子展示了从白色到黑色再到白色的水平渐变。


16
这个答案应该标记为解决方案。无论你想创建径向渐变还是水平渐变! - erdomester

-1

<!-- Drop Shadow Stack -->
<item>
    <shape android:shape="oval">
        <padding
            android:bottom="1dp"
            android:left="1dp"
            android:right="1dp"
            android:top="1dp" />

        <solid android:color="#00CCCCCC" />

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

        <solid android:color="#10CCCCCC" />

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

        <solid android:color="#20CCCCCC" />

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

        <solid android:color="#30CCCCCC" />

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

        <solid android:color="#50CCCCCC" />

        <corners android:radius="3dp" />
    </shape>
</item>

<!-- Background -->
<item>
    <shape android:shape="oval">
        <gradient
            android:startColor="@color/colorAccent_1"
            android:centerColor="@color/colorAccent_2"
            android:endColor="@color/colorAccent_3"
            android:angle="45"
            />
        <corners android:radius="3dp" />
    </shape>
</item>

<color name="colorAccent_1">#6f64d6</color>
<color name="colorAccent_2">#7668F8</color>
<color name="colorAccent_3">#6F63FF</color>

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