改变颜色时膨胀按钮的奇怪行为

2023-12-06

我正在尝试根据用户实时指定的输入为我的 Android 应用程序实现动态按钮膨胀。单击时,按钮的颜色从蓝色变为红色。

负责此操作的代码如下:

LayoutInflater layoutsInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.layout_for_buttons);

// Let's say that now we need only 3 buttons:
for (int i = 0; i < 3; i++) {
    RelativeLayout buttonLayout = (RelativeLayout) layoutsInflater
            .inflate(R.layout.button_layout, linearLayout, false);
    Button button = (Button) buttonLayout.getChildAt(0);
    button.setText("Button " + i);

    button.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View buttonView) {
            Button button = (Button) buttonView;
            GradientDrawable gradientDrawable = (GradientDrawable) button
                    .getBackground();
            gradientDrawable.setColor(Color.RED);
            gradientDrawable.invalidateSelf();
        }
    });

    linearLayout.addView(buttonLayout);
    linearLayout.invalidate();
}

我附加按钮的布局很简单LinearLayout:

<LinearLayout
    android:id="@+id/layout_for_buttons"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
</LinearLayout>

充气button_layout is a RelativeLayout由一个Button and a TextView:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10sp" >

    <Button
        android:id="@+id/button_view"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/button_bg"
        android:gravity="left"
        android:paddingBottom="7dip"
        android:paddingLeft="50sp"
        android:paddingTop="7dip"
        android:textColor="#FFFFFF"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/label_view"
        android:layout_width="24dip"
        android:layout_height="24dip"
        android:layout_marginLeft="13dip"
        android:layout_marginTop="8dip"
        android:gravity="center"
        android:text="Hi"
        android:textColor="#FFFFFF"
        android:textSize="20sp"
        android:textStyle="bold" />

</RelativeLayout>

@drawable/button_bg is a shape蓝色:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:padding="10dp"
    android:shape="rectangle" >
    <solid android:color="#0000ff" />
    <corners android:radius="10dp" />
</shape>

现在,当我运行该应用程序时,一切似乎都很好。单击后,第一个按钮不出所料地变成红色:

enter image description here

当我关闭并重新运行应用程序时,每个按钮都是蓝色的,这种行为符合我的期望。问题是,当我第二次重新运行应用程序,每个按钮都会变成红色(就好像已被单击一样):

enter image description here

正如文档中所写,inflate方法应该膨胀一个新的视图层次结构基于给定的 XML,那么什么可能造成这种情况呢?我还以为是一样的GradientDrawable可能在每个膨胀按钮之间共享,但调试器显示每个按钮都有自己的GradientDrawable实例。


看来我的问题已经解决了。那是一个GradientDrawable.mutate()必须调用该方法来防止这种行为:

Button button = (Button) buttonView;
GradientDrawable gradientDrawable = (GradientDrawable) button.getBackground();
gradientDrawable.mutate(); // needed line
gradientDrawable.setColor(Color.RED);
gradientDrawable.invalidateSelf();

它保证初始化的 Drawable 不会与从同一 XML 扩展的 Drawable 共享其状态,正如在文档:

使这个可绘制对象可变。此操作无法逆转。保证可变可绘制对象不会与任何其他可绘制对象共享其状态。当您需要修改从资源加载的可绘制对象的属性时,这特别有用。默认情况下,从同一资源加载的所有可绘制对象实例共享一个公共状态;如果修改一个实例的状态,所有其他实例都会收到相同的修改。在可变的 Drawable 上调用此方法不会产生任何效果。

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

改变颜色时膨胀按钮的奇怪行为 的相关文章

随机推荐

  • 使用 hibernate + spring mvc 获取自动生成的密钥,保存时

    我在用Spring MVC 休眠 Resource name sessionFactory private SessionFactory sessionFactory save public
  • 删除数组中重复的字符串

    我是 C 新手 我正在寻找一种从字符串数组中删除重复字符串的方法 如下所示 string exempleArray string1 string2 string1 代码之后应该如下所示 string1 string2 但顺序根本不重要 非常
  • 捕获“X-Frame-Options 禁止显示”[重复]

    这个问题在这里已经有答案了 我知道这个错误是无法克服的 但我想做的是 当我遇到无法嵌入的页面时 该页面只是作为弹出窗口加载 目前发生的情况是我被重定向到该页面 对于无法嵌入的页面 我在 Chrome 中看到以下错误 Refused to d
  • 在 JavaScript 中多次使用展开运算符?

    为什么扩展运算符不能多次使用 let arr 1 2 3 console log arr Array Array 1 console log arr Array Array 3 console log arr SyntaxError exp
  • 为什么我可以创建一个父类类型的变量

    当我上这些课时 public class Master public String test return I am the master object public String boeh return Only inside maste
  • ruby while 循环转换为 haskell

    我刚刚开始学习一些 Haskell 和函数式编程 但我发现很难掌握它 我正在尝试翻译一小段rubyHaskell 的代码 因为我喜欢函数式编程和 Haskell 提出的概念 更因为我来自数学领域 Haskell 看起来非常数学化 class
  • 在java中检索嵌套json中的所有键

    这是我写的程序 To change this template choose Tools Templates and open the template in the editor package javaapplication1 impo
  • iOS7中UISearchbar文本右对齐的方法

    你能告诉我如何在 iOS 7 中右对齐 UISearchbar 文本吗 我在iOS6中使用了这个 但现在它在iOS7中不起作用 hacking search bar UITextField searchField for UIView su
  • Android 中如何防止异常捕获?

    我正在尝试为 Android 开发一个应用程序 但我很难追踪在此过程中遇到的每个异常的来源和原因 我的代码在 Activity 中运行 如果我的一行引发异常 那么它不会停在该行并突出显示它 而是将我扔到 ActivityThread 类的代
  • Firebase:激活只读和非实时模式以提高浏览器性能

    激活只读和非实时模式以提高浏览器性能 我的项目中弹出消息 我也无法删除节点 我也读过这个https groups google com forum topic firebase talk qLxZCI8i47s 其中规定 如果您的 Fire
  • 更改 R 中多个 data.frame 对象中的单列名称

    我经常收到几个xts以日期作为行名称的对象 我必须改变那些xts物体进入data frame对象 但是当我这样做时 作为日期的行名称将成为名为的新第一列 ndex包含日期 但我需要那些Index要调用的列Date 因此 我想迭代地更改所有新
  • POST 请求中的 & 符号造成严重破坏

    我的 iPhone 应用程序有一个简单的 POST 它工作正常 除了传递一个 符号会导致后端中断 它几乎就像将其视为 GET 请求 符号分隔变量名称 我需要先进行某种编码吗 这是代码 NSString content NSString al
  • 如何在 Chrome 应用中手动清除 webview 的缓存?

    我正在开发一个 Chrome 应用程序 它在 webview 标签中显示一些网页内容 内容正在被缓存 当我编辑内容文件时 清除 Chrome 浏览器的缓存似乎并没有真正清除 webview 缓存 其中一篇文章建议每次 Chrome 应用程序
  • Ghostscript 目前可以将 PDF 转换为 PDF/X 吗?

    印刷厂要求我论文的 PDF 符合 PDF X1a 2001 标准 内容文件是使用编译的XeTeX LaTeX第二个 PDF 是封面设计Inkscape 0 48 我在这篇文章中找到的最接近的答案 https stackoverflow co
  • 修改图表_系列主题

    我正在尝试使用更改条形的颜色theme论点 但我得到一个错误 library quantmod getSymbols SPY from Sys Date 500 to Sys Date chart Series SPY chart Seri
  • Codeigniter 3 - Ajax 文件上传(您没有选择要上传的文件)

    控制器 function post if this gt input gt is ajax request show 404 exit data result false config upload path base url userfi
  • 面向对象设计:何时创建抽象类

    现在 我正在学习OOP 主要是c 我感兴趣的是创建一个无法实例化的类的主要原因是什么 何时创建抽象类的正确示例是什么 我发现自己过于热衷于以继承方式使用抽象类 系统中什么时候类是抽象的 什么时候类不应该是抽象的 是否有一些规则 例如 我创建
  • 在 Intellij Idea 中同时评估多个表达式

    在 Intellij Idea 中 我正在寻找一种使用一个命令在调试模式下评估多个表达式的方法 Normally I can evaluate single command with Right Click Evaluate Express
  • 为什么与 pthread 链接会导致分段错误?

    我有一个带有静态变量 abc cpp 的精简简单程序 include
  • 改变颜色时膨胀按钮的奇怪行为

    我正在尝试根据用户实时指定的输入为我的 Android 应用程序实现动态按钮膨胀 单击时 按钮的颜色从蓝色变为红色 负责此操作的代码如下 LayoutInflater layoutsInflater LayoutInflater getSy