天天看點

Drawable的getIntrinsicHeight()和getIntrinsicWidth()

版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。

今天遇到一個問題,一個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中:

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中,mTargetDensity的值預設為:

int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;

注意:res == null時,且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)已經被棄用,如果使用 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 

  * @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

<b>    本文轉自 一點點征服   部落格園部落格,原文連結:http://www.cnblogs.com/ldq2016/p/5377670.html</b><b>,如需轉載請自行聯系原作者 </b>