Drawable的getIntrinsicHeight()和getIntrinsicWidth()

Bitmap有getHeight()和getWidth(),而BitmapDrawable有getIntrinsicHeight()和getIntrinsicWidth()。

这两者有些区别。

看了下BitmapDrawable的源代码,getIntrinsicHeight()和getIntrinsicWidth()是根据像素密度计算的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void computeBitmapSize() {
final Bitmap bitmap = mBitmapState.mBitmap;
if (bitmap != null) {
mBitmapWidth = bitmap.getScaledWidth(mTargetDensity);
mBitmapHeight = bitmap.getScaledHeight(mTargetDensity);
} else {
mBitmapWidth = mBitmapHeight = -1;
}
}

@Override
public int getIntrinsicHeight() {
return mBitmapHeight;
}

而Bitmap的源码是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public int getScaledHeight(int targetDensity) {
return scaleFromDensity(getHeight(), mDensity, targetDensity);
}

/**
* @hide
*/
static public int scaleFromDensity(int size, int sdensity, int tdensity) {
if (sdensity == DENSITY_NONE || tdensity == DENSITY_NONE || sdensity == tdensity) {
return size;
}

// Scale by tdensity / sdensity, rounding up.
return ((size * tdensity) + (sdensity >> 1)) / sdensity;
}

可以看到,关键是mTargetDensity,这个值的默认值是:DisplayMetrics.DENSITY_MEDIUM,也就是160dpi,所以我们需要传入正确的mTargetDensity。

可以通过BitmapDrawable的setTargetDensity(getResources().getDisplayMetrics())的方式来设置正确的密度。

也可以通过BitmapDrawable新的构造方法,来设置

1
public BitmapDrawable(Resources res, Bitmap bitmap){...}

这个构造方法里会获取并赋值mTargetDensity。