为按钮背景颜色添加波纹效果到我的按钮?


124

我创建了一个按钮,我想向该按钮添加波纹效果!

我创建了一个按钮bg XML文件:(bg_btn.xml)

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient android:startColor="#FFFFFF" android:endColor="#00FF00" android:angle="270" />
<corners android:radius="3dp" />
<stroke android:width="5px" android:color="#000000" />
</shape>

这是我的涟漪效果文件:(ripple_bg.xml)

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="#f816a463"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="#f816a463" />
        </shape>
    </item>
</ripple>

这是我的按钮,我想添加波纹效果:

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="@+id/button"
android:layout_centerHorizontal="true"
android:layout_marginTop="173dp"
android:textColor="#fff"
android:background="@drawable/ripple_bg"
android:clickable="true" />

但是添加波纹效果后,按钮背景是透明的,并且仅在单击时显示按钮,如下所示:

点击之前

点击时

但是我既需要按钮背景色又需要波纹效果,我在Stack Overflow的不同博客中找到了一些代码,但是仍然无法正常工作!


请下次使屏幕截图更小..(在上传之前调整大小)
user25

@ user25,您也可以只在图片链接中添加lm。(请参阅我的编辑)
苏拉奇

Answers:


154

对于想要将渐变背景,拐角半径和波纹效果加在一起的人,这是另一个可绘制的xml:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorPrimaryDark">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimaryDark" />
            <corners android:radius="@dimen/button_radius_large" />
        </shape>
    </item>

    <item android:id="@android:id/background">
        <shape android:shape="rectangle">
            <gradient
                android:angle="90"
                android:endColor="@color/colorPrimaryLight"
                android:startColor="@color/colorPrimary"
                android:type="linear" />
            <corners android:radius="@dimen/button_radius_large" />
        </shape>
    </item>
</ripple>

将此添加到您的按钮的背景。

<Button
    ...
    android:background="@drawable/button_background" />

4
@pei你们如何从中获得此信息的?我的意思是你怎么知道有一个称为涟漪的XML元素可以完成这项工作?

1
这是材料设计中使用的概念之一。请开始在Android Studio中的可绘制xml中输入新的根标签,然后您应该就能看到所有可用的标签,包括ripple

1
口罩的用途是什么?
Prashant

10
这需要api级别21
M.kazem Akhgary

2
它有效,但未解释其工作方式。它应该与商品的ID相关。应该被引用。
oiyio '19

155

如果已有背景,则将其添加"?attr/selectableItemBackground"到视图的android:foreground属性中android:clickable="true"


并不总是工作,但你可以添加一个背景中接受的答案的评论中所指出的连锁反应
泰勒

我必须使用此解决方案,因为我为按钮使用了自定义背景。效果很好。
bnayagrawal

@ROAR,没错,但是至少:“这不是错误;应用程序只会忽略该属性。但是,如果该属性对应用程序的外观或功能很重要,则应考虑寻找一种替代方法来实现同样的结果,只是具有可用的属性,然后您可以选择在layout-vNN文件夹中创建布局的副本,该副本将在API NN或更高版本上使用,您可以在其中利用较新的属性。” 因此它在高于API 23的设备上运行良好,而在低于23的设备上被忽略(我们可以tools:ignore="UnusedAttribute)。
JorgeAmVF

如果没有Android支持库,则将?android:attr/selectableItemBackgroundandroid:attr而不是attr
周末

1
android:foreground属性对低于23的API级别没有影响
Vadim Kotov

67

将波纹效果/动画添加到Android按钮

只需将您的按钮background属性替换为android:background =“?attr / selectableItemBackground”,您的代码将如下所示。

      <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/selectableItemBackground"
        android:text="New Button" />

将波纹效果/动画添加到Android按钮的另一种方法

使用此方法,您可以自定义波纹效果颜色。首先,您必须在可绘制资源目录中创建一个xml文件。创建一个ripple_effect.xml文件并添加以下代码。 res / drawable / ripple_effect.xml

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="#f816a463"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="#f816a463" />
        </shape>
    </item>
</ripple>

并将按钮背景设置为上述可绘制资源文件

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/ripple_effect"
    android:padding="16dp"
    android:text="New Button" />

1
对我而言,没有出现涟漪效应。这只是一个按钮的颜色开关:/我的android版本是5.1.1,所以它应该可以工作。你能帮忙吗?我按照您的步骤进行了
UrviG '17

android:color应该不同于桅杆android:color,或者您想看到波纹效果
SpyZip

2
如果您想要背景,则只需在波纹中添加另一个项目,例如:<item android:drawable =“?attr / colorPrimary” />
泰勒(Tyler)

36

除了Jigar Patel的解决方案外,还将其添加到ripple.xml中可以避免按钮的透明背景。

<item
    android:id="@android:id/background"
    android:drawable="@color/your-color" />

完整的xml

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="@color/your-color"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="@color/your-color" />
        </shape>
    </item>
    <item
        android:id="@android:id/background"
        android:drawable="@color/your-color" />
</ripple>

在您的按钮中将此ripple.xml用作背景:

android:background="@drawable/ripple"

2
我们不需要使用<item android:id="@android:id/mask"> [...]。除非您想要椭圆形的面具。感谢您的回答!
Filipe Brito

无论如何,此<item android:id =“ @ android:id / mask”>是做什么的,我创建了2个具有和不具有该属性的相似元素,它们看起来完全一样
Sartheris Stormhammer

来自官方文档的@SartherisStormhammer:如果设置了遮罩层,则在覆盖其余子层的合成之前,将在该层上屏蔽涟漪效应。如果未设置遮罩层,则纹波效果将针对子层的复合遮罩。这是链接,developer.android.com/reference/android/graphics/drawable/...
萨德什[R

@SudheeshR只会使它更加混乱
Sartheris Stormhammer

@SartherisStormhammer来自该官方文档很显然,我认为。纹波效果将覆盖子图层/蒙版图层。请再次阅读该文档,您会明白这一点。
Sudheesh R

32

当按钮具有可绘制对象的背景时,我们可以向前景色参数添加波纹效果。

    <Button
    android:layout_width="wrap_content"
    android:layout_height="40dp"
    android:gravity="center"
    android:layout_centerHorizontal="true"                                                             
    android:background="@drawable/shape_login_button"
    android:foreground="?attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    android:text="@string/action_button_login"
     />

在参数下方添加波纹效果

   android:foreground="?attr/selectableItemBackgroundBorderless"
   android:clickable="true"

供参考,请参见下面的链接 https://jascode.wordpress.com/2017/11/11/how-to-add-ripple-effect-to-an-android-app/


2
属性android:foreground对低于23的API级别没有影响
阿里卡其

这种方法的一个缺点是,即使我的按钮背景为椭圆形,波纹也会传播到矩形边缘。
iCantC

13

AppCompat v7 +

如果不加前缀,则?android:应用程序将崩溃。

您应该根据自己的喜好使用"?android:attr/selectableItemBackground""?android:attr/selectableItemBackgroundBorderless"。我更喜欢Borderless

您可以将其放入android:backgroundandroid:foreground保留现有属性。

元素必须具有android:clickable="true"android:focusable="true"才能使其正常工作,但是true默认情况下,许多元素(例如按钮)都具有。

<Button
    ...
    android:background="@color/white"
    android:foreground="?android:attr/selectableItemBackgroundBorderless"
/>
<TextView
    ...
    android:background="?android:attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    android:focusable="true"
/>

以编程方式(Java)

TypedValue value = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
myView.setBackgroundResource(value.resourceId);
myView.setFocusable(true); // If needed for view type

以编程方式(科特琳)

val value = TypedValue()
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, value, true)
myView.setBackgroundResource(value.resourceId)
myView.setFocusable(true) // If needed for view type

可重复使用的Kotlin扩展功能

myView.ripple()

fun View.ripple(): View {
    val value = TypedValue()
    context.theme.resolveAttribute(android.R.attr.selectableItemBackground, value, true)
    setBackgroundResource(value.resourceId)
    isFocusable = true // Required for some view types
    return this
}

7

添加前景和可点击属性对我有用。

<Button
    ... 
    android:background="@color/your_color"
    android:foreground="?attr/selectableItemBackgroundBorderless"
    android:clickable="true" />

6

除了Sudheesh R

将波纹效果/动画添加到带有角的按钮矩形形状的Android按钮

创建xml文件res / drawable / your_file_name.xml

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="@color/colorWhite"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimaryDark" />
            <corners android:radius="50dp" />
        </shape>
    </item>

    <item android:id="@android:id/background">
        <shape android:shape="rectangle">
            <gradient
                android:angle="90"
                android:endColor="@color/colorAccent"
                android:startColor="@color/colorPrimary"
                android:type="linear" />
            <corners android:radius="50dp" />
        </shape>
    </item>
</ripple>

4

当您使用android:background时,您将用空白替换按钮的大部分样式和外观。

更新:从AppCompat的23.0.0版本开始,有一个新的Widget.AppCompat.Button。一种彩色样式,该样式将主题的colorButtonNormal用作禁用的颜色,将colorAccent用作启用的颜色。

这使您可以通过以下方式直接将其应用于按钮

<Button
 ...
style="@style/Widget.AppCompat.Button.Colored" />

您可以在v21目录中使用可绘制背景作为背景,例如:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?attr/colorControlHighlight">
<item android:drawable="?attr/colorPrimary"/>
</ripple>

这样可以确保您的背景色是?attr / colorPrimary,并具有使用默认?attr / colorControlHighlight(您也可以根据需要在主题中设置)的默认波纹动画。

注意:您必须为v21以下版本创建自定义选择器:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/primaryPressed"            android:state_pressed="true"/>
<item android:drawable="@color/primaryFocused" android:state_focused="true"/>
<item android:drawable="@color/primary"/>
</selector>

即时通讯使用minSDK lvl 21
rakcode

没有v21可绘制文件夹,只有一个文件夹本身就是v21文件夹
rakcode

是的,我也使用了此API,如果我在单击我的应用程序后崩溃了
便

实际上,我以调试模式在手机中测试了我的应用,并且我的操作系统是CyanogenMod13(Android 6,
Marshmellow

4

试试这个

<Button
            android:id="@+id/btn_location"
            android:layout_width="121dp"
            android:layout_height="38dp"
            android:layout_gravity="center"
            android:layout_marginBottom="24dp"
            android:layout_marginTop="24dp"
            android:foreground="?attr/selectableItemBackgroundBorderless"
            android:clickable="true"
            android:background="@drawable/btn_corner"
            android:gravity="center_vertical|center_horizontal"
            android:paddingLeft="13dp"
            android:paddingRight="13dp"
            android:text="Save"
            android:textColor="@color/color_white" />

4

一种简单的方法是设置一个此处概述的视图主题。

some_view.xml

<ImageView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="?attr/selectableItemBackgroundBorderless"
   android:focusable="true"
   android:src="@drawable/up_arrow"
   android:theme="@style/SomeButtonTheme"/>

some_style.xml

<style name="SomeButtonTheme" >
   <item name="colorControlHighlight">@color/someColor</item>
</style>

3

只需使用:

android:backgroundTint="#f816a463"

代替:

android:background="#f816a463"

别忘了将您更改Buttonandroid.support.v7.widget.AppCompatButton


1
不利的是,如果您需要一个按钮来填充100%的水平屏幕,则不会。
Filipe Brito

1

以下是使用<ripple>标记的一种替代解决方案(我个人不希望这样做,因为颜色不是“默认”):

为按钮背景创建一个可绘制对象,并将其包含<item android:drawable="?attr/selectableItemBackground"><layer-list>

然后(我认为这是重要的部分)以编程方式设置backgroundResource(R.drawable.custom_button)在您的按钮实例上。

活动/片段

Button btn_temp = view.findViewById(R.id.btn_temp);
btn_temp.setBackgroundResource(R.drawable.custom_button);

布局

<Button
    android:id="@+id/btn_temp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/custom_button"
    android:text="Test" />

custom_button.xml

<?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="@android:color/white" />
            <corners android:radius="10dp" />
        </shape>
    </item>
    <item android:drawable="?attr/selectableItemBackground" />
</layer-list>

为什么在布局xml定义Button的背景的同时,再次以编程方式再次设置backgroundResource?
SunnyShiny9
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.