BitmapDrawable设置alpha时的一个BUG

本文探讨了在Android中,通过BitmapDrawable设置透明度(alpha)时存在的一个BUG。由于BitmapDrawable的ConstantState导致多个Drawable共享同一个BitmapState,从而影响到其他相同Drawable的alpha值。当对一个BitmapDrawable进行alpha动画时,会影响到其他使用同样资源的Drawable。建议避免使用BitmapDrawable进行alpha动画,以防止未预期的透明度变化问题。
摘要由CSDN通过智能技术生成

最近太忙,所以很久没有写新文章了。这次我们来讨论一下Drawable设置alpha的一个BUG。


一般来说,Drawable做alpha动画都是通过设置alpha来实现。比如使用

drawable.setAlpha(0);
...
drawable.setAlpha(255);
其中0是全透明,255是全不透明。


其实这里有一个很大的BUG,其中牵涉到Drawable的类型。我们以BitmapDrawable和NinePatchDrawable来举例。


在NinePatchDrawable中,设置Alpha值的代码如下:

    @Override
    public void setAlpha(int alpha) {
        if (mPaint == null && alpha == 0xFF) {
            // Fast common case -- leave at normal alpha.
            return;
        }
        getPaint().setAlpha(alpha);
        invalidateSelf();
    }
其中getPaint()的代码如下:
    public Paint getPaint() {
        if (mPaint == null) {
            mPaint = new Paint();
            mPaint.setDither(DEFAULT_DITHER);
        }
        return mPaint;
    }
也就是说,NinePatchDrawable设置alpha值的时候,会使用本身所有的一个Paint对象来实现Alpha值的变化。


再回头看看BitmapDrawable的实现。

    @Override
    public void setAlpha(int alpha) {
        int oldAlpha = mBitmapState.mPaint.getAlpha();
        if (alpha != oldAlpha) {
            mBitmapState.mPaint.setAlpha(alpha);
            invalidateSelf();
        }
    }
请注意,BitmapDrawable中,Paint对象实际是BitmapState的变量,而不是BitmapDrawable本身的。让我们找找BitmapState是从哪儿来的。

一般来说,我们的Drawable都是从resource里面读取而不是自己创建,所以,我们先聚焦从resource读取drawable的情况,所有从resource中读取Drawable的调用最终会调用到loadDrawable()。如下所示:

    /*package*/ Drawable loadDrawable(TypedValue value, int id)
            throws NotFoundException {

        if (TRACE_FOR_PRELOAD) {
            // Log only framework resources
            if ((id >>> 24) == 0x1) {
                final String name = getResourceName(id);
                if (name != null) an
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值