zoukankan      html  css  js  c++  java
  • 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中:

    1. private void computeBitmapSize() {  
    2.       mBitmapWidth = mBitmap.getScaledWidth(mTargetDensity);  
    3.       mBitmapHeight = mBitmap.getScaledHeight(mTargetDensity);  
    4.   }  
      private void computeBitmapSize() {
            mBitmapWidth = mBitmap.getScaledWidth(mTargetDensity);
            mBitmapHeight = mBitmap.getScaledHeight(mTargetDensity);
        }
    1. @Override  
    2.    public int getIntrinsicWidth() {  
    3.        return mBitmapWidth;  
    4.    }  
    5.   
    6.    @Override  
    7.    public int getIntrinsicHeight() {  
    8.        return mBitmapHeight;  
    9.    }  
     @Override
        public int getIntrinsicWidth() {
            return mBitmapWidth;
        }
    
        @Override
        public int getIntrinsicHeight() {
            return mBitmapHeight;
        }

    1. private BitmapDrawable(BitmapState state, Resources res) {  
    2.         mBitmapState = state;  
    3.         if (res != null) {  
    4.             mTargetDensity = res.getDisplayMetrics().densityDpi;  
    5.         } else if (state != null) {  
    6.             mTargetDensity = state.mTargetDensity;  
    7.         } else {  
    8.             mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;  
    9.         }  
    10.         setBitmap(state.mBitmap);  
    11.     }  
    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;

    1. /** 
    2.     * Create an empty drawable, setting initial target density based on 
    3.     * the display metrics of the resources. 
    4.     */  
    5.    public BitmapDrawable(Resources res) {  
    6.        mBitmapState = new BitmapState((Bitmap) null);  
    7.        mBitmapState.mTargetDensity = mTargetDensity;  
    8.    }  
    9.   
    10.    /** 
    11.     * Create drawable from a bitmap, not dealing with density. 
    12.     * @deprecated Use {@link #BitmapDrawable(Resources, Bitmap)} to ensure 
    13.     * that the drawable has correctly set its target density. 
    14.     */  
    15.    @Deprecated  
    16.    public BitmapDrawable(Bitmap bitmap) {  
    17.        this(new BitmapState(bitmap), null);  
    18.    }  
     /**
         * 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);
        }
    
    1.     /** 
    2.      * Create drawable from a bitmap, setting initial target density based on 
    3.      * the display metrics of the resources. 
    4.      */  
    5.     public BitmapDrawable(Resources res, Bitmap bitmap) {  
    6.         this(new BitmapState(bitmap), res);  
    7.         mBitmapState.mTargetDensity = mTargetDensity;  
    8.     }  
        /**
         * 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:

    1.  public static final int DENSITY_DEFAULT = DENSITY_MEDIUM;  
     public static final int DENSITY_DEFAULT = DENSITY_MEDIUM;
    

    在Bitmap中:

    1. /** 
    2.   * Convenience method that returns the width of this bitmap divided 
    3.   * by the density scale factor. 
    4.   * 
    5.   * @param targetDensity The density of the target canvas of the bitmap. 
    6.   * @return The scaled width of this bitmap, according to the density scale factor. 
    7.   */  
    8.  public int getScaledWidth(int targetDensity) {  
    9.      return scaleFromDensity(getWidth(), mDensity, targetDensity);  
    10.  }  
    11.   
    12.  /** 
    13.   * Convenience method that returns the height of this bitmap divided 
    14.   * by the density scale factor. 
    15.   * 
    16.   * @param targetDensity The density of the target canvas of the bitmap. 
    17.   * @return The scaled height of this bitmap, according to the density scale factor. 
    18.   */  
    19.  public int getScaledHeight(int targetDensity) {  
    20.      return scaleFromDensity(getHeight(), mDensity, targetDensity);  
    21.  }  
    22.    
    23.  /** 
    24.   * @hide 
    25.   */  
    26.  static public int scaleFromDensity(int size, int sdensity, int tdensity) {  
    27.      if (sdensity == DENSITY_NONE || sdensity == tdensity) {  
    28.          return size;  
    29.      }  
    30.        
    31.      // Scale by tdensity / sdensity, rounding up.  
    32.      return ( (size * tdensity) + (sdensity >> 1) ) / sdensity;  
    33.  }  
       /**
         * 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

  • 相关阅读:
    [经验] 如何在虚拟机上安装 CentOS
    [经验] Java 使用 netty 框架, 向 Unity 客户端的 C# 实现通信[2]
    [经验] Java 使用 netty 框架, 向 Unity 客户端的 C# 实现通信 [1]
    [经验] 关于 Java 中的非空判断
    [经验] Java Web 项目怎么部署到 Linux 系统上
    求和
    引用与指针
    C++学习前言
    大O
    ubuntu连接不上mysql问题
  • 原文地址:https://www.cnblogs.com/ldq2016/p/5377670.html
Copyright © 2011-2022 走看看