Today I encountered a problem where a bitmap is encapsulated into bitmapdrawable, bitmapdrawable drawable = new bitmapdrawable (BMP ),
Bitmap. getwidth ()! = Bitmapdrawable. getintrinsicwidth (). Some problems are caused:
Check the source code. The problem is as follows:
In bitmapdrawable, when assigning values to mbitmapwidth, you must scale the value according to the density. The default value is 160, and the mdpi is used:
Mtargetdensity = displaymetrics. density_default;
In the case that the density of bitmap is 240, the scaling is:
The formula is approximately equal to: drawabledensity * BMP width/BMP density ====>> 160*72/240, so getintrinsicheight () is 48
In bitmapdrawable:
private void computeBitmapSize() { mBitmapWidth = mBitmap.getScaledWidth(mTargetDensity); mBitmapHeight = mBitmap.getScaledHeight(mTargetDensity); }
@Override public int getIntrinsicWidth() { return mBitmapWidth; } @Override public int getIntrinsicHeight() { return mBitmapHeight; }
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); }
In buttonstate, the default value of mtargetdensity is:
Int mtargetdensity = displaymetrics. density_default;
Note: When res = NULL, and state! = NULL, mtargetdensity = state. mtargetdensity;
/** * 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 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) has been discarded. If bitmapdrawable (bitmap BMP, resources res) is used
In displaymetrics:
public static final int DENSITY_DEFAULT = DENSITY_MEDIUM;
In bitmap:
/** * 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; }
In this case, only the following changes are made:
Method 1:
Bitmapdrawable BMP drawable = new bitmapdrawable (BMP, getresources );
Method 2:
Bitmapdrawable BMP drawable = new bitmapdrawable (BMP );
BMP drawable. settargetdensity (getresources (). getresources (). getdisplaymetrics ());