getBackground().setAlpha(0)引发的血案 页面背景变灰色底

开篇先扯下场景哈,大家应该都见过一个很常见的UI交互,默认进一个页面看见顶部TitleBar背景是透明的,随着向上滑动查看底下内容的时候,TitleBar背景逐渐变不透明直至不透明度100%;
为了实现这个效果,我们通常的做法是监听向上滚动的距离,然后跟设定的某个最大滚动距离去求百分比,再把这个得到的不透明度百分比设置给TitleBar的Background。

上代码:
if (scrollY >= topBannerHeight) {  
    bding.topTitleLayout.getBackground().setAlpha(255);
} else if (scrollY > 5) {
    int alpha = scrollY * 255 / topBannerHeight; 
    bding.topTitleLayout.getBackground().setAlpha(alpha);
} else {    
    bding.topTitleLayout.getBackground().setAlpha(0);  
}

于是这样简单的几行代码,就成功实现了TitleBar渐变的需求了。
But却因为这几行代码,一开始出现了一个莫名其妙的bug通过治标不治本的方法解决了,但没想到过了很久后又引发了大面积的血案,So不得不根治病因了。
下面讲述下过程:

  1. 一个莫名奇妙的bug
    在画某个页面的时候,需要用通用的一个绿色作为背景,接着很常规地就在xml里面加上android:background="@color/default_green"。然后run app调试的时候发现,那个View背景竟然没出现绿色,是灰色底。这就让我很尴尬了,页面上其他view的背景色都是正常的就唯独它一枝独秀,后面立马去检查values文件夹中colors.xml中default_green对应色值,一看是正常的啊,怎么会不正确显示呢?而且在预览布局xml文件的时候,显示也是正常的。后面为了验证是不是这个颜色出问题了, 还傻傻地把它换成其他color,结果run后发现都正常显示了,后面我又去再代码中去添加背景色
    setBackgroundResource(R.color.default_green)
    结果发现也是么有显示出来,后面我使出终极大招写了个drawable资源文件
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/default_green"></solid>
    </shape>
    配置了下,run后发现就正常了,当时也想不到啥原因也就不了了之了。

  2. 很久后又引发了大面积的血案
    很久后再做新一期需求的时候,又来了个页面需要做TitleBar渐变的需求,只不过这次要求渐变的背景色是白色,接着就写了同样地代码去实现。这次xml背景配置的是android:background="@color/white",然后开发过程中发现从TitleBar渐变的页面回到主页面的时候,许多都被成灰色底,样式全变了,再点击其他页面看看发现白色都不再是白色了。第一感觉是因为系统内存不足,绘制ui出问题了,试着关闭app杀掉进程再打开发现主页面正常了,安慰自己这是debug状态,等打release包后应该就不会发生了。
    但是墨菲定律是经得起考验的,果不其然第二天产品妹子就在群里截图@我,问我怎么主页面底色都变灰了,我瞬间才意识到这不是系统内存不足、debug等状态才会产生的不过,又联想到之前出现的那个莫名奇妙的bug,最终确定本质原因应该是一样的,得做并案处理。


接下来就去搜xml background color 无效的问题,最终发现了新大陆Drawable.mutate()这里写图片描述
简单翻译:
使这个drawable变得状态不定。这个操作不能还原(变为不定后就不能变为原来的状态)。一个状态不定的drawable可以保证它不与其他任何一个drawabe共享它的状态。这对于你需要更改从同一资源加载来的drawable的属性时非常有用。默认情况下,所有的从同一资源(R.drawable.XXX)加载来的drawable实例都共享一个共用的状态,如果你更改一个实例的状态,其他所有的实例都会收到相同的通知。这个方法对于已经是mutable的drawable没有效果。

知道了原因后,再想想之前绿色背景显示不出来的情况,就是因为有一个页面是把默认绿色做了透明度渐变,之所以没有大面积出现bug,因为直接用@color/default_green作背景的地方很少,而这次白色不一样了,有太多地方是直接使用@color/white作背景的,所以大面积爆发了,真的很感谢这次bug大爆发让我get到一个早该知道的知识点!

最后说一下解决方案:

getBackground().setAlpha(alpha)
=》
getBackground().mutate().setAlpha(alpha)

看了这篇https://blog.csdn.net/bzlj2912009596/article/details/79707023

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值