Android开发中几乎每天都要接触ImageView这个控件。这个控件可以作为加载图片的容器。ImageView给我们提供了五种设置图片资源的方法:
- setImageBitmap(Bitmap bm)
- setImageDrawable(Drawable drawable)
- setImageResource(int resId)
- setImageURI(Uri uri)
- setImageIcon(Icon icon)
下面就通过源码来看看这5个方法的区别。
1. setImageBitmap(Bitmap bm)
setImageBitmap方法中,先把bitmap放在一个BitmapDrawable中,然后调用的setImageDrawable方法。
public void setImageBitmap(Bitmap bm) {
// Hacky fix to force setImageDrawable to do a full setImageDrawable
// instead of doing an object reference comparison
mDrawable = null;
if (mRecycleableBitmapDrawable == null) {
mRecycleableBitmapDrawable = new BitmapDrawable(mContext.getResources(), bm);
} else {
mRecycleableBitmapDrawable.setBitmap(bm);
}
setImageDrawable(mRecycleableBitmapDrawable);
}
2. setImageDrawable(Drawable drawable)
setImageDrawable方法里面先调用了updateDrawable()方法,然后判断了drawable的宽高是否有改变,如果发生了改变则会调用requestLayout()方法,最后调用invalidate()方法,让新设置的drawable生效。
updateDrawable()
这个方法里用于更新drawable的可见性、宽高、边界、颜色等。requestLayout()
这个方法会根据View树逐级向上传递,最后由ViewRootImpl#requestLayout方法处理该事件。ViewRootImpl#requestLayout中会调用scheduleTraversals()方法,这是一个异步方法,会调用performTraversals()方法。在performTraversals()方法中会先后调用performMeasure()和performLayout()方法。然后视条件调用performDraw()方法。invalidate()
该方法会不断向父容器请求刷新并计算需要重绘的区域,最后会传递到ViewRootImpl中触发performTraversals方法,然后调用performDraw()进行重绘。
/**
* Sets a drawable as the content of this ImageView.
*
* @param drawable t