如题,很多用过ListView的人都会遇到这种问题,很多人只是片面的解决该问题,就是将cacheColorHint 设置为#00000000。接下来就为大家介绍问题出现的原因。
ListView是Android广泛应用的View组件,它很容易使用。但是有时很难去理解它。
其中一个最常见的问题就是当你给ListView使用自定义背景的时候。像所有其他Android控件一样,默认的listView背景是透明的,这就意味着你可以透过ListView看到后面窗体的颜色(系统默认颜色是#191919)。此外,ListView默认是启用“边缘褪色”的效果,如下截图:看截图的最上端,列表第一项的文字正逐渐变黑。这种效果用于Android系统向用户表明该容器是可以被滑动的。
这种渐变效果是用Canvas.saveLayerAlpha()结合PorterDuff.Mode的DST_OUT(有关PorterDuff.Mode用法,可以参看ApiDemos中graphics模块的代码)模式实现的。不幸的是,当你在ListView或者窗体上运用自定义的背景的时候会出现下列问题。如下图,左边截图展示了列表的正常情况,右边截图展示了当你触摸滑动列表时出现的问题。
出现这种问题是因为Android框架默认在ListView上启用“渐变效果”(上面提到的用PorterDuff.Mode的DST_OUT实现的)。这种渐变效果实现方式很好,但是要付出代价,会导致降低绘图性能。因为它需要捕获一部分呈现在画面以外的位图。
因为ListView显示的背景在大部分时间是固定的,所以在滚动的过程中如果实时地去将当前每个Item的显示内容跟背景进行混合运算,会花费昂贵代价。因此引进了一项优化,叫做“cache color hint”。“cache color hint”的值是RGB形式的颜色值。当“cache color hint”被设置后,ListView就知道需要绘制一致的背景色,并用一个简单的渐变方式替换用DST_OUT实现的渐变。这个简单渐变的颜色是从完全透明到“cache color hint”的RGB值的渐变。但是这仍然不能解释为什么在滚动的时候List变成黑色。
正如前面所说的,ListView默认的背景是透明或者半透明的。这就意味着当Listview重绘子视图的时候,子视图与窗体背景混合运算,使得在触摸滑动的时候会付出昂贵的代价。为了提升在滑动时绘制的性能,Android框架会重用“cache color hint”。当“cache color hint”被设置后,Android框架会复制所有的list的子视图一个位图(Bitmap)中,并用color hint的值进行填充。然后ListView将位图传送到屏幕上。这些位图是不透明的,又因为系统默认的“cache color hint”值是#191919,所以当你滑动的时候List的每一项都是黑色的。
解决这个问题,你可以将“cache color hint”设置一个合适的RGB值,或者禁用“cache color hint”。你可以在代码(setCacheColorHint())或者XML(android:cacheColorHint)中设置。如果想禁用“cache color hint”,将其值设置为 #00000000即可。
|