将颜色过滤器添加到Drawable会使用相同的Drawable更改所有按钮

Cha*_*ltz 29 android

我有一个屏幕,其中多个按钮使用相同的背景Drawable.我有可重用的代码,我在各种项目中使用它来添加一个OnTouch监听器,在触摸按钮时添加灰色滤色器.这通常可以正常工作,但在这种情况下,当按下任何按钮时,所有按钮都会着色.

我在http://developer.android.com/guide/topics/graphics/2d-graphics.html中看到了一个解释:

注意:无论您为其实例化多少个不同的对象,项目中的每个唯一资源都只能维护一个状态.例如,如果您从同一图像资源中实例化两个Drawable对象,则更改其中一个Drawable的属性(例如alpha),然后它也会影响另一个.

建议的解决方案是使用TweenAnimation,它似乎不适用于滤色器.

我还看到了Android:克隆一个drawable,以便使用过滤器创建一个StateListDrawable,建议使用drawable.getConstantState().newDrawable().这似乎没有什么区别.我猜测只要使用相同的物理图像文件,所有Drawables都会受到使用相同资源对任何其他Drawable的更改的影响.

除了创建第二个背景图像以显示按下状态之外,还有什么解决方案?有一个简单的程序化解决方案,我可以添加到我的代码并在每个项目中使用,这将是一件好事.

小智 68

应该适合您的示例:

Drawable buttonBackground = context.getResources().getDrawable(R.drawable.bg);
buttonBackground = buttonBackground.mutate();

//Set your filter here
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这仅在您调用getDrawable时有效.如果你在一个变量中缓存了drawable并在其上调用了mutate(),那么它们仍将共享该状态. (11认同)
  • 非常感谢!我想使用StateListDrawable使用相同的drawable,这解决了它!这是来自Android文档:_Make这个drawable mutable.此操作无法逆转.可变drawable保证不与任何其他drawable共享其状态.当您需要修改从资源加载的drawable的属性时,这尤其有用.默认情况下,从同一资源加载的所有drawables实例共享一个公共状态; 如果修改一个实例的状态,则所有其他实例将收到相同的修改._ (3认同)