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

Posted

技术标签:

【中文标题】使用按钮背景颜色为我的按钮添加波纹效果?【英文标题】:Add ripple effect to my button with button background color? 【发布时间】:2017-02-21 20:18:34 【问题描述】:

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

我创建了一个按钮 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: 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_
android:layout_
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,您也可以在图片链接中添加lm。 (见我的编辑) 那些想要转发foreground 属性的人,使用这个hack 来实现向后兼容性 - ***.com/a/65213848/4694013 【参考方案1】:

对于那些想要将渐变背景、圆角半径和波纹效果加在一起的人来说,这是另一个可绘制的 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" />

PS:此答案适用于 android api 21 及更高版本。

【讨论】:

@pei 你们是如何获得这些信息的?我的意思是你怎么知道有一个叫做涟漪的 XML 元素来完成这项工作? 这是材料设计中使用的概念之一。请开始在 Android Studio 中的可绘制 xml 中输入新的根标签,然后您应该能够看到所有可用的标签,包括 ripple 掩码项有什么用? 这需要 api 级别 21 它可以工作,但没有解释它是如何工作的。它应该与项目的ID相关。应该被引用。【参考方案2】:

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

【讨论】:

并不总是有效,但您可以为波纹效果添加背景,如已接受答案的 cmets 中所述 我不得不使用这个解决方案,因为我为我的按钮使用了自定义背景。效果很好。 @ROAR,没错,但至少:“这不是错误;应用程序将简单地忽略该属性。但是,如果该属性对您的应用程序的外观或功能很重要,您应该考虑找到一种仅使用可用属性来实现相同结果的替代方法,然后您可以选择在 layout-vNN 文件夹中创建布局的副本,该文件夹将用于 API NN 或更高版本,您可以在其中利用更新的属性。”所以它在 API 23 以上的设备上运行良好,在低于 API 23 时被忽略(我们可以tools:ignore="UnusedAttribute)。 如果没有 Android 支持库,它将是 ?android:attr/selectableItemBackgroundandroid:attr 而不是 attr android:foreground 属性对低于 23 的 API 级别没有影响【参考方案3】:

将涟漪效果/动画添加到 Android 按钮

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

      <Button
        android:layout_
        android:layout_
        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_
    android:layout_
    android:background="@drawable/ripple_effect"
    android:padding="16dp"
    android:text="New Button" />

【讨论】:

对我来说,涟漪效应没有出现。它只是按钮的颜色开关:/ 我的 android 版本是 5.1.1,所以它应该可以工作。你能帮忙吗?我跟着你的脚步 android:color 应该和桅杆android:color 不同,不然你想看到涟漪效果 如果你想要一个背景,你只需在波纹中添加另一个项目,例如:【参考方案4】:

除了 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"

【讨论】:

我们不需要使用&lt;item android:id="@android:id/mask"&gt; [...]。除非你想要一个椭圆形的面具。感谢您的回答! 这个 有什么作用,我创建了 2 个类似的元素,有和没有那个属性,它们看起来完全一样 @SartherisStormhammer 来自官方文档:如果设置了遮罩层,则波纹效果将在该层被绘制到剩余子层的合成上之前被遮盖。如果未设置遮罩层,则波纹效果将针对子层的合成进行遮罩。这是链接,developer.android.com/reference/android/graphics/drawable/… @SudheeshR 只会让人更加困惑 @SartherisStormhammer 从该官方文档中我认为很清楚。涟漪效果将绘制在子/蒙版图层上。请再读一遍文档,你会明白的。【参考方案5】:

当按钮具有可绘制的背景时,我们可以为前景参数添加波纹效果。检查下面的代码它是否适用于具有不同背景的按钮

    <Button
    android:layout_
    android:layout_
    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/

【讨论】:

属性 android:foreground 对低于 23 的 API 级别没有影响 这种方法的一个缺点是,即使我的按钮背景是椭圆形的,波纹也会传播到矩形边缘。【参考方案6】:

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

以编程方式 (Kotlin)

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

【讨论】:

如果您添加?android,您将不会使用 AppCompat 库,而是来自操作系统的库(因此它会在 apiandroid: 命名空间前缀的情况下使用它。 感谢您的留言?。我希望大多数开发者的最低等级都在 11 以上,所以没问题【参考方案7】:

一种简单的方法是设置一个视图主题,如here 所述。

some_view.xml

<ImageView
   android:layout_
   android:layout_
   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>

【讨论】:

【参考方案8】:

除了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>

【讨论】:

【参考方案9】:

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

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

【讨论】:

API 23 级以上【参考方案10】:

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

更新:从 AppCompat 的 23.0.0 版本开始,有一个新的 Widget.AppCompat.Button.A 彩色样式,它使用主题的 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>

【讨论】:

im 使用 minSDK 21 级 没有v21可绘制文件夹,只有一个文件夹本身就是v21文件夹 是的,我也用过这个API,如果我在点击我的应用程序后使用这个API就会崩溃 实际上,我正在使用调试模式在我的手机中测试我的应用,我的操作系统是 CyanogenMod13 (Android 6, Marshmellow)【参考方案11】:

试试这个

<Button
            android:id="@+id/btn_location"
            android:layout_
            android:layout_
            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" />

【讨论】:

【参考方案12】:

只需使用:

android:backgroundTint="#f816a463"

代替:

android:background="#f816a463"

不要忘记将您的 Button 更改为 android.support.v7.widget.AppCompatButton

【讨论】:

不好的是,如果你需要一个按钮来 100% 填充水平屏幕,你就不会。【参考方案13】:

使用&lt;ripple&gt; 标签(我个人不喜欢这样做,因为颜色不是“默认”)的替代解决方案如下:

为按钮背景创建一个drawable,并在&lt;layer-list&gt;中包含&lt;item android:drawable="?attr/selectableItemBackground"&gt;

然后(我认为这是重要的部分)以编程方式在您的按钮实例上设置 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_
    android:layout_
    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>

【讨论】:

为什么要以编程方式再次设置backgroundResource,而layout xml定义了Button的背景?【参考方案14】:

setForeground 被添加到 API 级别 23。如果您需要在foreground 属性上进行中继,请利用RevealAnimator 的力量!

 <View
   android:id="@+id/circular_reveal"
   android:layout_
   android:layout_
   android:background="@color/primaryMilk_22"
   android:elevation="@dimen/margin_20"
   android:visibility="invisible" />

使用 kotlin ext 函数,就是 osm !

fun View.circularReveal() 
    val cx: Int = width / 2
    val cy: Int = height / 2
    val finalRadius: Int =
        width.coerceAtLeast(height)
    val anim: Animator = ViewAnimationUtils.createCircularReveal(
        this,
        cx,
        cy,
        0f,
        finalRadius.toFloat()
    )
    anim.interpolator = AccelerateDecelerateInterpolator()
    anim.duration = 400
    isVisible = true
    anim.start()
    anim.doOnEnd 
        isVisible = false
    

【讨论】:

以上是关于使用按钮背景颜色为我的按钮添加波纹效果?的主要内容,如果未能解决你的问题,请参考以下文章

Android 波纹背景颜色

如何在保留其他样式属性的同时更改 Android Button 波纹颜色?

Android,设置按钮的背景颜色会失去涟漪效果

html中点击按钮怎样改变div背景颜色

js改变单选按钮背景图片,怎么更改文字颜色呢?效果如图

Iphone UIButton 背景颜色