2 usniyo usniyo 于 2013.05.09 10:24 提问

关于Android View与Drawable的问题,求高人解惑

调用View.invalidate()方法,就会请求View重新draw()。可是我看了invalidate()与相关的方法,并没有与draw()有直接的关系。请问invalidate()是如何使View重新draw()的?

Drawable.mutate()方法为了不产生新的对象,直接返回了它自身。既然是这样,那为什么mutate()以后同一个图像资源能够有不同的常态(比如透明度)?在BitmapDrawable中在第一次mutate()的时候新生成一个BitmapState常态,后面的就是直接返回它自身了。第一次常态对象改变了倒还可以理解,可后面的我就不明白了。求高人解惑,非常感谢!

1个回答

franzhong
franzhong   2013.05.09 11:51
已采纳

1:invalidate刷新原理比较复杂

invaliddate=>父view=>Handler=>performTraversals()=>draw()=>onDraw();

/* ============================detail====================================
其继承的父views cheduleTraversals()方法向Handler发送消息
viewRoot 处理其消息
case DO_TRAVERSAL: 
         performTraversals();
performTraversals()方法,调用private void draw(boolean fullRedrawNeeded)
其中含有
mView.draw(canvas); 
接着
if (!dirtyOpaque) onDraw(canvas);  
*/

2:不能发图片,我就简要说明吧
不是为了省内存,恰恰相反,原生的drawable是共享部份数据才是省内存
其中共享部分就是constant state(常态)
你想啊,N张图片用一个常态,我若想改这个值,如Alpha那么所有图片都变了,就像
变量static变量一样了
而使用mutate以后,会复制constant state,drawable还是共享的,这也算是解决了低于1.5版本的一个"bug"

franzhong
franzhong
接近 5 年之前 回复
usniyo
usniyo 我明白了,mutate以后,将constant state拷贝了过来,共用图像数据,是不是这样的?
接近 5 年之前 回复
usniyo
usniyo 非常感谢!可是关于mutate我还不明白,既然返回自身,那constant state还是原来的那个啊,为什么会互不影响?public Drawable mutate() { if (!mMutated && super.mutate() == this) { mBitmapState = new BitmapState(mBitmapState); mMutated = true; } return this; }
接近 5 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!