DrawableのgetIntrinsicHeight()とgetIntrinsicWidth()


今日、BitmapがBitmapDrawableにカプセル化され、BitmapDrawable=new BitmapDrawable(bmp)、
Bitmap.getWidth() != BitmapDrawable.getIntrinsicWidth().いくつかの問題が発生しました.
ソースコードを表示します.問題は次のとおりです.
BitmapDrawableでmBitmapWidthに値を割り当てる場合、densityに従ってスケールします.デフォルト値は160、mdpiの場合:
 mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
Bitmapのdensityが240の場合は、次のようにスケールされます.
式は、drawableDesity*bmpWidth/bmpDesity====>>160*72/240に等しいので、getIntrinsicHeight()は48です.
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);
    }


ButtonStateでは、mTargetDesityの値のデフォルトは次のとおりです.
int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
注意:res==nullの場合、state!=nullの場合、mTargetDesity=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)はすでに廃棄されており、使用する場合は
BitmapDrawable(Bitmap bmp,Resources res)
コンストラクタ
DisplayMetricsで:
 public static final int DENSITY_DEFAULT = DENSITY_MEDIUM;

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;
    }

このように、以下の変更を行うしかありません.
方法1:
BitmapDrawable bmpDrawable = new BitmapDrawable(bmp,getResources);
方法2:
BitmapDrawable bmpDrawable = new BitmapDrawable(bmp);
bmpDrawable.setTargetDensity(getResources().getResources().getDisplayMetrics());