您的位置:首页 > 其它

Drawable的getIntrinsicHeight()和getIntrinsicWidth()

2016-04-11 11:32 393 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。

今天遇到一个问题,一个Bitmap封装到BitmapDrawable中 ,BitmapDrawable drawable = new BitmapDrawable(bmp),

Bitmap.getWidth() != BitmapDrawable.getIntrinsicWidth().导致一些问题:

查看源代码,问题如下:

在BitmapDrawable中,给mBitmapWidth赋值时,要根据density缩放,其默认值是160,mdpi的情况:

mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;

而在Bitmap的density是240情况下,将缩放:

公式约等于为:drawableDensity * bmpWidth / bmpDensity ======>> 160 * 72 / 240 ,所以getIntrinsicHeight()为48

在BitmapDrawable中:

[java] view plain copy

print?

private void computeBitmapSize() {

mBitmapWidth = mBitmap.getScaledWidth(mTargetDensity);

mBitmapHeight = mBitmap.getScaledHeight(mTargetDensity);

}

private void computeBitmapSize() {
mBitmapWidth = mBitmap.getScaledWidth(mTargetDensity);
mBitmapHeight = mBitmap.getScaledHeight(mTargetDensity);
}


[java] view plain copy

print?

@Override

public int getIntrinsicWidth() {

return mBitmapWidth;

}

@Override

public int getIntrinsicHeight() {

return mBitmapHeight;

}

@Override
public int getIntrinsicWidth() {
return mBitmapWidth;
}

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


[java] view plain copy

print?

private BitmapDrawable(BitmapState state, Resources res) {

mBitmapState = state;

if (res != null) {

mTargetDensity = res.getDisplayMetrics().densityDpi;

} else if (state != null) {

mTargetDensity = state.mTargetDensity;

} else {

mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;

}

setBitmap(state.mBitmap);

}

private BitmapDrawable(BitmapState state, Resources res) {
mBitmapState = state;
if (res != null) {
mTargetDensity = res.getDisplayMetrics().densityDpi;
} else if (state != null) {
mTargetDensity = state.mTargetDensity;
} else {
mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
}
setBitmap(state.mBitmap);
}


在ButtonState中,mTargetDensity的值默认为:

int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;

注意:res == null时,且state != null时,mTargetDensity = state.mTargetDensity;

[java] view plain copy

print?

/**

* Create an empty drawable, setting initial target density based on

* the display metrics of the resources.

*/

public BitmapDrawable(Resources res) {

mBitmapState = new BitmapState((Bitmap) null);

mBitmapState.mTargetDensity = mTargetDensity;

}

/**

* Create drawable from a bitmap, not dealing with density.

* @deprecated Use {@link #BitmapDrawable(Resources, Bitmap)} to ensure

* that the drawable has correctly set its target density.

*/

@Deprecated

public BitmapDrawable(Bitmap bitmap) {

this(new BitmapState(bitmap), null);

}

/**
* Create an empty drawable, setting initial target density based on
* the display metrics of the resources.
*/
public BitmapDrawable(Resources res) {
mBitmapState = new BitmapState((Bitmap) null);
mBitmapState.mTargetDensity = mTargetDensity;
}

/**
* Create drawable from a bitmap, not dealing with density.
* @deprecated Use {@link #BitmapDrawable(Resources, Bitmap)} to ensure
* that the drawable has correctly set its target density.
*/
@Deprecated
public BitmapDrawable(Bitmap bitmap) {
this(new BitmapState(bitmap), null);
}


[java] view plain copy

print?

/**

* Create drawable from a bitmap, setting initial target density based on

* the display metrics of the resources.

*/

public BitmapDrawable(Resources res, Bitmap bitmap) {

this(new BitmapState(bitmap), res);

mBitmapState.mTargetDensity = mTargetDensity;

}

/**
* Create drawable from a bitmap, setting initial target density based on
* the display metrics of the resources.
*/
public BitmapDrawable(Resources res, Bitmap bitmap) {
this(new BitmapState(bitmap), res);
mBitmapState.mTargetDensity = mTargetDensity;
}


其中,BitmapDrawable(Bitmap bmp)已经被弃用,如果使用 BitmapDrawable(Bitmap bmp,Resources res)构造函数

在DisplayMetrics:

[java] view plain copy

print?

public static final int DENSITY_DEFAULT = DENSITY_MEDIUM;

public static final int DENSITY_DEFAULT = DENSITY_MEDIUM;


在Bitmap中:

[java] view plain copy

print?

/**

* Convenience method that returns the width of this bitmap divided

* by the density scale factor.

*

* @param targetDensity The density of the target canvas of the bitmap.

* @return The scaled width of this bitmap, according to the density scale factor.

*/

public int getScaledWidth(int targetDensity) {

return scaleFromDensity(getWidth(), mDensity, targetDensity);

}

/**

* Convenience method that returns the height of this bitmap divided

* by the density scale factor.

*

* @param targetDensity The density of the target canvas of the bitmap.

* @return The scaled height of this bitmap, according to the density scale factor.

*/

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 || sdensity == tdensity) {

return size;

}

// Scale by tdensity / sdensity, rounding up.

return ( (size * tdensity) + (sdensity >> 1) ) / sdensity;

}

/**
* Convenience method that returns the width of this bitmap divided
* by the density scale factor.
*
* @param targetDensity The density of the target canvas of the bitmap.
* @return The scaled width of this bitmap, according to the density scale factor.
*/
public int getScaledWidth(int targetDensity) {
return scaleFromDensity(getWidth(), mDensity, targetDensity);
}

/**
* Convenience method that returns the height of this bitmap divided
* by the density scale factor.
*
* @param targetDensity The density of the target canvas of the bitmap.
* @return The scaled height of this bitmap, according to the density scale factor.
*/
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 || sdensity == tdensity) {
return size;
}

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


如此,只有做如下改动:

方法一:

BitmapDrawable bmpDrawable = new BitmapDrawable(bmp,getResources);

方法二:

BitmapDrawable bmpDrawable = new BitmapDrawable(bmp);

bmpDrawable.setTargetDensity(getResources().getResources().getDisplayMetrics());

借鉴: http://blog.csdn.net/jason_wks/article/details/8283224
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: