Drawable.mutate()的补充说明

转自http://blog.sina.com.cn/s/blog_5f8817250100m86s.html

前一段时间,我写一个自定义的ImageButton,其类名MyImageButton。它主要有以下功能:
1,显示文本,手动画上去的,能随意设置文字显示的位置。
2,按下时显示按下的背景图。
3,当disable时,在原来背景图上显示一层半透明。
4,按下去能保持focuse的背景。
5,支持xml属性。
6,能显示overlay图片
7,.......

其实实现这些功能很简单,无非就是画吧,然后就是一堆逻辑处理,按下了没有,是不是应该画focus的背景等等,反正就是画。这些功能由于很简单,并不是我写这篇文章的目的,我主要想说一下如何实现disable的功能。先看看效果图吧。

Android <wbr>自定义的ImageButton <wbr>(Drawable)


前两个Button就是自定义的Button,Apply button的状态是enable,cancel button的状态是disable。这是怎么做的呢?请看下面代码:
Drawable bkDrawable = this.getBackground(). mutate();
if (null != bkDrawable)
{
           if (enable)
           {
                         bkDrawable.clearColorFilter();
           }
           else
           {
                          bkDrawable.setColorFilter(m_disableColor, PorterDuff.Mode.DST_OUT);
           }
           this.setBackgroundDrawable(bkDrawable);
}

说明一下:
m_disableColor = Color.argb(168, 255, 75, 75);这就是BUTTON不可能时盖在背景上面的颜色。
这几句话的意思就是,如果不可用,enable == false时,就给背景drawable设置color filter,如果enable == true时,就把color filter清了,调用clearColorFilter方法。
请注意第一句话中用红色标识出来的方法mutate(),它是干什么的呢?大家可以去查看一个Drawable::muteate方法的说明:
Make this drawable mutable. This operation cannot be reversed. A mutable drawable is guaranteed to not share its state with any other drawable. This is especially useful when you need to modify properties of drawables loaded from resources.  By default, all drawables instances loaded from the same resource share a common state; if you modify the state of one instance, all the other instances will receive the same modification. Calling this method on a mutable Drawable will have no effect.
翻译过来就是:
使这个drawable变得状态不定。这个操作不能还原(变为不定后就不能变为原来的状态)。一个状态不定的drawable可以保证它不与其他任何一个drawabe共享它的状态。这对于你需要更改从同一资源加载来的drawable的属性时非常有用。 默认情况下,所有的从同一资源(R.drawable.XXX)加载来的drawable实例都共享一个共用的状态,如果你更改一个实例的状态,其他所有的实例都会收到相同的通知。这个方法对于已经是mutable的drawable没有效果。

问题又来了,我这里为什么要用mutate()这个方法呢,不用行吗?答:不用不行,为什么呢?
根据上面的说明,drawable如果是从同一个资源加载来的,这些drawable虽说不是同一实例,但他们共享同一状态,setColorFilter其实就是在改它们的状态,我测试用的例子中的ImageButton,它们的背景资源是同一个,那么这两个ImageButton中的背景drawable就共享同一状态,假如我把Apply设置了disable,那么Cancel中的drawable也成了disable的,所以画出来的就不对了。所以在这里在调用mutate()方法。

下面看看,我不调用mutate()方法的效果,Click me Button的点击处理是把apply和cancel按钮变为可用或不可用。
this.setContentView(R.layout.atest);
m_apply = (MyImageButton)this.findViewById(R.id.btnApply1111);
m_cancel = (MyImageButton)this.findViewById(R.id.btnCancel1111);
m_cancel.setEnabled(false);
Button btn = (Button)this.findViewById(R.id.btnSwitch);
btn.setOnClickListener(new View.OnClickListener()
{
             public void onClick(View v)
             {
                         m_apply.setEnabled(!m_apply.isEnabled());
                         m_cancel.setEnabled(!m_cancel.isEnabled());
             }
});
 
这里我把cancel设置成不可用,按理说应该得到上图那样的效果,看看实际的效果:

Android <wbr>自定义的ImageButton <wbr>(Drawable)



不一样了吧,都改了。
所以说,mutate()方法是必须要用的,使每个drawable的状态不相互依赖,相互共享。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值