如何渐变填充按钮的背景?

2023-12-01

我必须创建一个带有渐变填充的彩色按钮(从按钮的中间沿 Y 轴开始)。如果我将按钮的背景属性设置为我想要的颜色,我会丢失rounded按钮的外观和感觉以及渐变填充(它看起来像TextView有背景)。

另外,我希望当用户按下按钮时改变这种颜色。我可以通过选择器 XML 指定它吗(颜色状态列表)?

任何可以帮助我的教程或链接都将受到赞赏。

Thanks.


我相信你想要做的是让你的按钮在正常状态、按下状态、聚焦状态等时显示不同的渐变。这可以使用 XML 来完成(在 res/drawable 中创建一个 selecter.xml 文件来引用res/drawable 中的 shape.xml 文件,每个文件都包含一个渐变元素,然后将按钮的背景设置为您创建的选择器.xml 文件。)但是,XML 路由仅允许您使用两个(或可选的三个)定义渐变)静态颜色并且无法控制颜色停止点的位置。编程解决方案将为您提供更大的灵活性,并允许您动态更改颜色。以下是名为 GradientLab 的 Android 项目的示例。

res/layouts 中的 main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical"
  style="@style/LayoutArea"
>
 <TextView
  style="@style/LayoutRow"
  android:text="@string/hello" />
 <Button
  style="@style/RowButton"
  android:id="@+id/btn1"
  android:text="1" />
 <Button
  style="@style/RowButton"
  android:id="@+id/btn2"
  android:text="2" />
 <Button
  style="@style/RowButton"
  android:id="@+id/btn3"
  android:text="3" />
</LinearLayout>

res/values 中的 styles.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <style name="LayoutArea">
  <item name="android:layout_width">fill_parent</item>
  <item name="android:layout_height">fill_parent</item>
 </style>
 <style name="LayoutRow">
  <item name="android:layout_width">fill_parent</item>
  <item name="android:layout_height">wrap_content</item>
 </style>
 <style name="LayoutColumn">
  <item name="android:layout_width">wrap_content</item>
  <item name="android:layout_height">fill_parent</item>
 </style>
 <style name="LayoutItem">
  <item name="android:layout_width">wrap_content</item>
  <item name="android:layout_height">wrap_content</item>
 </style>
 <style name="RowButton" parent="LayoutRow">
  <item name="android:layout_weight">1</item>
  <item name="android:layout_margin">8dp</item>
  <item name="android:gravity">center_horizontal</item>
 </style>
</resources>

android.examples 中的 GradientLab.java 演示了使用带按钮的渐变:

package android.example;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.Button;
import android.widget.LinearLayout;

public class GradientLab extends Activity {
    // Layout fields
    protected LinearLayout mainLayout;
    public static Button btn1 = null;
    public static Button btn2 = null;
    public static Button btn3 = null;

    // Members
    private int[] normalColors = new int[4];
    private int[] focusedColors = new int[2];
    private int[] disabledColors = new int[1];
    private int defaultSkinR = 94;
    private int defaultSkinG = 128;
    private int defaultSkinB = 219;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /*
         * This creates View objects from the xml file. The xml file should
         * define all views and all static attributes.
         */
        mainLayout = (LinearLayout) getLayoutInflater().inflate(R.layout.main,
                null);

        normalColors[0] = Color.argb(255, defaultSkinR, defaultSkinG,
                defaultSkinB);
        normalColors[1] = Color.argb(255, 217, 217, 217);
        normalColors[2] = Color.argb(191, defaultSkinR, defaultSkinG,
                defaultSkinB);
        normalColors[3] = Color.argb(140, defaultSkinR, defaultSkinG,
                defaultSkinB);

        focusedColors[0] = Color.argb(229, 242, 242, 242);
        focusedColors[1] = Color.BLUE;

        UIGradientSelector gradientSelector1 = new UIGradientSelector(
                normalColors, focusedColors, null);
        UIGradientSelector gradientSelector2 = new UIGradientSelector(
                normalColors, focusedColors, null);

        disabledColors[0] = Color.argb(153, 216, 216, 216);
        UIGradientDrawable disabledGradient = new UIGradientDrawable(
                disabledColors);

        btn1 = (Button) mainLayout.findViewById(R.id.btn1);
        btn1.setBackgroundDrawable(gradientSelector1);

        btn2 = (Button) mainLayout.findViewById(R.id.btn2);
        btn2.setBackgroundDrawable(gradientSelector2);

        btn3 = (Button) mainLayout.findViewById(R.id.btn3);
        btn3.setBackgroundDrawable(disabledGradient);

        setContentView(mainLayout);
    }
}

android.examples 中的 UIGradientSelector.java 根据按钮状态选择渐变:

package android.example;

import android.graphics.drawable.StateListDrawable;

/**
 * {@link StateListDrawable} that controls selection of
 * {@link UIGradientDrawable} based on the three basic button states.
 */
public class UIGradientSelector extends StateListDrawable {

    /**
     * {@link UIGradientSelector} that selects the {@link UIGradientDrawable}
     * defined by the colors for the three basic button states.
     * 
     * @param normalColors
     *            Array of primitive ints that define the gradient colors for a
     *            button in its normal state.
     * @param focusedColors
     *            Array of primitive ints that define the gradient colors for a
     *            button in its focused state.
     * @param pressedColors
     *            Array of primitive ints that define the gradient colors for a
     *            button in its pressed state. If the array is null, then
     *            focusedColors will be used for the pressed state.
     */
    public UIGradientSelector(int[] normalColors, int[] focusedColors,
            int[] pressedColors) {
        int stateFocused = android.R.attr.state_focused;
        int statePressed = android.R.attr.state_pressed;
        UIGradientDrawable normalGradient = new UIGradientDrawable(normalColors);
        UIGradientDrawable focusedGradient = new UIGradientDrawable(
                focusedColors);
        UIGradientDrawable pressedGradient;

        if (pressedColors == null) {
            pressedGradient = focusedGradient;
        } else {
            pressedGradient = new UIGradientDrawable(pressedColors);
        }

        addState(new int[] { stateFocused }, focusedGradient);
        addState(new int[] { statePressed }, pressedGradient);
        addState(new int[] { -statePressed, -stateFocused }, normalGradient);
    }
}

android.examples 中的 UIGradientDrawable.java 绘制表面:

package android.example;

import android.graphics.drawable.PaintDrawable;
import android.graphics.drawable.shapes.RectShape;

/**
 * {@link PaintDrawable} that paints the surface via a {@link UIGradientShader}.
 */
public class UIGradientDrawable extends PaintDrawable {

    /**
     * {@link UIGradientDrawable} with an initial shape of a rounded rectangle
     * that transitions evenly between the specified colors.
     * 
     * @param colors
     *            Array of primitive ints that contain the argb values of the
     *            color to use for transitioning.
     */
    public UIGradientDrawable(int[] colors) {
        UIGradientShader gradientShader = new UIGradientShader(colors);
        setShape(new RectShape());
        setCornerRadius(8);
        setShaderFactory(gradientShader);
        setDither(true);
    }

}

android.examples 中的 UIGradientShader.java 处理实际的过渡:

package android.example;

import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Shader;
import android.graphics.drawable.ShapeDrawable.ShaderFactory;

/**
 * {@link ShaderFactory} that uses a {@link LinearGradient} to transition
 * between specified colors. Any number of colors may be specified.
 */
public class UIGradientShader extends ShaderFactory {
    private int[] colors;
    private float[] positions;

    /**
     * {@link UIGradientShader} that spaces color transitions evenly across the
     * painting surface.
     * 
     * @param colors
     *            Array of primitive ints that contain the argb values of the
     *            color to use for transitioning. If the array contains only one
     *            color, then an argb of (0, 0, 0, 0) will be used for the end
     *            color of the transition. If the array is set to null or
     *            contains zero colors, then the transition will be from an argb
     *            of (255, 255, 255, 255) to and argb of (0, 0, 0, 0).
     * 
     * @see Color
     */
    public UIGradientShader(int[] colors) {
        init(colors, null);
    }

    /**
     * {@link UIGradientShader} that spaces color transitions across the
     * painting surface as specified.
     * 
     * @param colors
     *            Array of primitive ints that contain the argb values of the
     *            color to use for transitioning. If the array contains only one
     *            color, then an argb of (0, 0, 0, 0) will be used for the end
     *            color of the transition. If the array is set to null or
     *            contains zero colors, then the transition will be from an argb
     *            of (255, 255, 255, 255) to and argb of (0, 0, 0, 0).
     * @param positions
     *            Array of primitive floats that contain the position of the
     *            transition points. If the array is null, then the color
     *            transitions will be spaced evenly.
     */
    public UIGradientShader(int[] colors, float[] positions) {
        init(colors, positions);
    }

    private void init(int[] colors, float[] positions) {
        if (colors == null || colors.length == 0) {
            this.colors = new int[2];
            this.colors[0] = Color.argb(255, 255, 255, 255);
            this.colors[1] = Color.argb(0, 0, 0, 0);
        } else if (colors.length == 1) {
            this.colors = new int[2];
            this.colors[0] = colors[0];
            this.colors[1] = Color.argb(0, 0, 0, 0);
        } else {
            this.colors = colors;
        }

        this.positions = positions;
    }

    public Shader resize(int width, int height) {
        LinearGradient lg = new LinearGradient(0, 0, 0, height, colors,
                positions, Shader.TileMode.REPEAT);
        return lg;
    }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何渐变填充按钮的背景? 的相关文章

  • Eclipse Android 项目总是在调试中启动

    我觉得问这个问题很愚蠢 遇到这个问题更愚蠢 我有一个 Android 项目 到目前为止一直运行良好 但几天前 在我没有做任何我所知道的特别事情的情况下 无论我尝试什么 我的项目总是在调试中启动自己 单击调试或运行会给我相同的结果 我尝试查看
  • Android 卷页动画

    我对 Android 动画有点陌生 目前我正在开发一个故事活动 需要像 iPhone 中那样使用卷页动画 我发现 iPhone 中有一种方法可以做到这一点 但我仍然找不到在android中做的方法 所以请帮我解决这个问题 谢谢大家 谷歌代码
  • 有没有一种方法可以在不使用意图的情况下在活动之间发送数据?

    我有一个对于每个用户来说都是唯一的用户名 我想将其发送到某个活动 但我不想使用意图 create an intent and sends username Intent intent new Intent RegisterOwner thi
  • ViewFlipper中的VideoView在播放视频时是透明的

    我有一个 Activity 在 ViewFlipper 中设置了两个视图 其中一个视图是带有 GLSurfaceView 和一些其他小部件的布局 另一个视图只有带有 TextView 和 VideoView 的布局 当我单击 GLSurfa
  • Facebook4j API:搜索

    我正在使用 Facebook4j 通过关键字获取状态 facebook4j conf ConfigurationBuilder fac new facebook4j conf ConfigurationBuilder fac setDebu
  • 如何将Android中的cURL发送到REST服务

    我是 android 新手 我想从 REST 服务获取一些数据 但在初始化发送到 REST 服务的方法时遇到一些问题 您知道 REST 服务使用 cURL 来操作一些数据 POST PUT GET DELETE 现在如何在 android
  • 如何将现有的 SQLite3 数据库导入 Room?

    好吧 我在桌面上使用 SQLite3 创建了一个只需要读取的某些信息的数据库 我正在制作的应用程序不需要在此表中插入或删除信息 我在 Room 数据库层上做了相当多的谷歌搜索 所有文档都需要在构建应用程序时在 Room 中创建一个新的数据库
  • 在没有 BluetoothManagerCallback 的情况下调用 getBluetoothService

    我正进入 状态getBluetoothService called with no BluetoothManagerCallback在我的 Android 应用程序中经常出现错误 我不知道是什么原因导致这个或任何有关蓝牙管理器回调的事情 谁
  • 动态地将textView添加到线性布局中

    我在这里的某个地方读过这篇文章 但我完全迷失了 但我需要一些帮助 我的应用程序正在将列名称从 sqlite 拉入数组中 我想创建一个文本视图并为每个视图编辑文本 通过数组的大小 我记得在某处读过 您可以将 textViews 变量名称视为数
  • 合并 dex 程序类型已存在时出错:android.support.v4.os.ResultReceiver$MyResultReceiver

    合并dex时出错 以下是依赖项 ext anko version 0 10 5 support lib 1 0 0 alpha1 room lib 1 1 0 dependencies implementation org jetbrain
  • java.net.ProtocolException:流意外结束

    我面临一个奇怪的问题 并且无法调试它 我已经实现了上传数据流的逻辑 并使用 Volley 来实现相同的功能 我在HurlStack addBodyIfExistsapi 以便可以处理 application octet stream 类型的
  • Android 媒体播放器搜索栏

    我有一个创建 播放和处理媒体播放器 只是音频 的服务 但我在主要活动中有一个搜索栏 我想自然地显示音频文件的进度并允许用户搜索到不同的位置 我花了很长时间才弄清楚 将 UI 中的搜索栏连接到服务中的媒体播放器的最佳或正确方法是什么 我将这样
  • 如何使用共享首选项在两个 Android 应用程序之间共享数据?

    我有两个应用程序 App1 和 App2 我想使用共享首选项在 App1 中保存数据并在 App2 中访问 反之亦然 我可以在 App1 中保存数据并在 App2 中访问数据 但反之则不行 这就是我现在正在做的 在清单中 android s
  • 将触摸事件从 NestedScrollView 传递到父视图

    我在 NestedScrollView 下方有一个 ViewPager 宽度一些顶部填充 以及 ClipToPadding false 和透明背景 如图像 我的 ViewPager 无法获取触摸事件并且无法工作 我怎么解决这个问题 我无法更
  • LinearLayout:防止最后一个孩子被之前的大文本视图推出或挤压

    我有一个LinearLayout里面有两个孩子 第一个是TextView对于动态内容 第二个是一个按钮 我的问题是按钮被推出其父级或被挤压到不再可见的程度 我想要TextView认识到其父母与第二个孩子一起没有更多空间 并开始新的一行 而不
  • 如何为 flutter 绘图应用实现橡皮擦功能

    有一个关于通过 flutter 创建绘图应用程序的视频 YouTube https www youtube com watch v yyHhloFMNNA 它支持当用户点击屏幕时绘制线 点 但我找不到像 Android 本机那样擦除用户绘制
  • 可用屏幕的尺寸

    我使用的是 Nexus 7 1280x800 android 4 2 2 API 17 我想获取屏幕的大小 将其划分为相同高度和宽度的正方形部分 我正在使用 FrameLayout 我的方块是 ImageView 的子类 我这样做 cont
  • 在循环中按名称访问变量

    我正在开发一个 Android 项目 并且有很多可绘制对象 这些绘图的名称都类似于icon 0 png icon 1 png icon 100 png 我想将这些可绘制对象的所有资源 ID 添加到整数 ArrayList 中 对于那些不了解
  • Android Volley - 发布请求 - 无法在线工作

    我试图通过 Volley 发出 POST 请求 它在我的本地主机中工作得很好 但是当我将它移动到网络服务器时 响应为空 Java代码 RequestQueue queue Volley newRequestQueue this String
  • Android Google 地图无法在当前主题中找到样式“mapViewStyle”

    添加谷歌地图视图时 我扩展了MapView 使用xml编辑器将其添加到活动中 并将我的谷歌地图api密钥手动添加到布局xml文件中 我的权限在清单文件中允许互联网 我想知道的是 在 xml 编辑器中 我收到错误 无法在当前主题中找到样式 m

随机推荐

  • 目录枚举以跳过文件夹

    我有一段可爱的代码 它对我来说非常出色 只需获取多次搜索等所需的所有文件 public static IEnumerable
  • MIFARE Classic:如何找到良好的访问字节值

    我的目标是仅进行 KEY A 身份验证并禁用 Key B 用于存储数据的空间 我阅读了这些文档 http www nxp com documents data sheet MF1S503x pdf http dangerousthings
  • GetContentHeight() 无法正常工作

    我正在尝试检索网络视图内容的高度 它包含一个 html 字符串 问题是 getContentHeight 总是返回相同的值 392 无论 html 字符串有多长 这个问题已经让我抓狂了 让我猜测一下 您的内容不是从网络或文件系统加载的 而是
  • 从字符串获取 DbSet

    ADO NET 用户首次尝试 EF 我正在尝试从表名字符串中获取一个表 比我想象的还要难 基本上我在这里 var tableName Name Entities Measure measureType var table Activator
  • 如何将 JSON api 日期与 FSCalendar 进行比较并在表格视图中显示事件?

    我在日历中显示了事件点 但无法根据表格视图中的月份显示相同的事件 我想显示这些事件 例如如果我们更改月份并且表格视图数据事件应该更改 我很困惑如何做到这一点 我正在使用 FSCalendar 来显示 dot 和 tableview 等事件
  • 如何重新安装 NetBeans?所有可用组件(包和运行时)都已安装,如何继续?

    NetBeans 重新安装出现问题 第一个工作正常 所有可用组件均已安装 单击 取消 退出安装程序 没办法继续下去了 之前 我使用 全部 完整下载选项 215 MB 下载并安装了 NetBeans IDE 8 1 的窗口版本 其中包含 Ne
  • iText - 可点击的图像应该打开 MS Word 附件

    如何使图像可点击以便打开附加的 ms word 文档 我这里有一些 PDF 其中有一些图像 ms word 图标 图标下方有 ms word 文件名 通过单击图像打开附加的 ms word 文档 我想知道如何使用 iText 库执行此操作
  • 为什么有些人在循环宏的子句中使用关键字?

    它能解决任何问题吗 根据 PCL 的第一个脚注 如果不是关键字 它会将符号保留在当前包中 由于所有关键字都被保留在关键字包中 因此可以防止多个符号被保留在不同的包中 但还有其他优点吗 它会产生什么问题 我猜一定有问题 因为这不是普遍的惯例
  • 极坐标图中的箭头

    我试图绘制串联 R L C 电路中电阻器 电容器和电感器两端电压的相量 我已经完成了所有的计算 我可以用正常的方式得到一个像样的图ax plot theta r 我想让相量向量看起来像箭头 我一直在尝试使用ax arrow 0 0 thet
  • 为什么需要 Lambda 函数将值传递给 @onclick 调用的方法?

    我是 Blazor 以及一般的 Web 开发人员 的新手 我跟着Microsoft 的 Blazor Web 应用程序待办事项列表教程 在完成上述教程后 我想进一步在每个列表元素旁边添加按钮以将它们从列表中删除 这是我为实现这一目标而编写的
  • 使用Postman发送PATCH到Asp.net Core webapi时出错

    我有一个模型 public class Order public Guid Id get set public IEnumerable
  • matplotlib twinx 在循环内

    我有一个循环 在特定条件下 例如出现 3 次 我想用 twinx 绘制两个数据集 所以例如最后我在左 y 上有 3 个图 在右 y 上有 3 个图 当我使用通常的 twinx 时 循环的右 y 值不正确 我应该如何修改此示例代码才能使其正确
  • 何时要求子句表达式需要加括号? (偶然的双关语)

    这给出了一个错误 template
  • document.getElementById 替换 angular4 / typescript 中的?

    我在实践工作中使用 Angular4 这对我来说是新的 为了获取 HTML 元素及其值 我使用了
  • 如何在ListView列表项中添加节标题

    我想开发 国家历史 Android应用程序 但我有一个问题 我无法将国家 地区标题放入列表视图列表项中 我想放标题 例如 非洲 北非 撒哈拉以南非洲 亚洲 北亚 西亚和中亚 南亚和东南亚 欧洲 北美和中美洲 北美洲 大洋洲 南美洲 这是我的
  • 如何用多个分隔符分割字符串并保留分隔符?

    我有例如这个字符串 abc 现在 我想把它分成 分隔符 我知道我可以使用 String split 来实现这一点 但有没有办法可以通过这个符号来分割 if 但又不会丢失它 就像如果我使用 split 我会得到这个string abc 而且我
  • 用于维护计数器和聚合的 Firebase 控制服务器

    It s a 已知问题firebase 没有简单的方法来计算项目 我计划创建一个严重依赖计数和其他聚合的应用程序 我担心按照建议的规则创建此应用程序的计数器here将非常复杂且难以维护 所以我想到了这个模式 我将保留一个服务器来侦听数据库中
  • 强制 Sympy 在 MathJax Jupyter 中打印数学

    我正在使用 VSCode 和 Jupyter 来处理 Sympy 通常 它以 MathJax 格式打印数学方程 sympy 文档说 在IPython笔记本中 它将使用MathJax来渲染LATEX MathJax 输出 但是 当我安装 ma
  • 捕获 Mysqli 错误

    我定义了一个自定义错误处理程序 它捕获所有异常并将它们保存到日志中 现在 如果我在 mysqli 查询中出现语法错误 例如拼写错误 页面将在此时完全停止加载 不会引发异常 因此不会触发错误处理程序并且不会记录任何内容 这是正常的吗 我应该检
  • 如何渐变填充按钮的背景?

    我必须创建一个带有渐变填充的彩色按钮 从按钮的中间沿 Y 轴开始 如果我将按钮的背景属性设置为我想要的颜色 我会丢失rounded按钮的外观和感觉以及渐变填充 它看起来像TextView有背景 另外 我希望当用户按下按钮时改变这种颜色 我可