版权声明:本文为博主原创文章,未经博主允许不得转载。

今天遇到一个问题,一个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. @Override
  6. public int getIntrinsicHeight() {
  7. return mBitmapHeight;
  8. }
 @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. * Create drawable from a bitmap, not dealing with density.
  11. * @deprecated Use {@link #BitmapDrawable(Resources, Bitmap)} to ensure
  12. * that the drawable has correctly set its target density.
  13. */
  14. @Deprecated
  15. public BitmapDrawable(Bitmap bitmap) {
  16. this(new BitmapState(bitmap), null);
  17. }
 /**
* 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. * Convenience method that returns the height of this bitmap divided
  13. * by the density scale factor.
  14. *
  15. * @param targetDensity The density of the target canvas of the bitmap.
  16. * @return The scaled height of this bitmap, according to the density scale factor.
  17. */
  18. public int getScaledHeight(int targetDensity) {
  19. return scaleFromDensity(getHeight(), mDensity, targetDensity);
  20. }
  21. /**
  22. * @hide
  23. */
  24. static public int scaleFromDensity(int size, int sdensity, int tdensity) {
  25. if (sdensity == DENSITY_NONE || sdensity == tdensity) {
  26. return size;
  27. }
  28. // Scale by tdensity / sdensity, rounding up.
  29. return ( (size * tdensity) + (sdensity >> 1) ) / sdensity;
  30. }
   /**
* 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

Drawable的getIntrinsicHeight()和getIntrinsicWidth()的更多相关文章

  1. 玩转Android之Drawable的使用

    Drawable天天用,可你是否对Drawable家族有一个完整的认知?今天我们就来系统的学习一下Drawable的使用. 1.概述 用过Drawable的筒子都知道Drawable有很多种,有的时候 ...

  2. android的Drawable详解

    Drawable简介 Drawable有很多种,用来表示一种图像的概念,但他们又不完全是图像,他们是用过颜色构建出来的各种图像的表现形式.Drawable一般都是通过xml来定义的 ,当然我们也可以通 ...

  3. [转]自定义Drawable实现灵动的红鲤鱼动画(上篇)

    此篇中的小鱼动画是模仿国外一个大牛做的flash动画,第一眼就爱上它了,简约灵动又不失美学,于是抽空试着尝试了一下,如下是我用Android实现的效果图:   小鱼儿 由于整个绘制分析过程比较繁琐所以 ...

  4. Android 自定义列表指示器

    在联系人界面 可以看到这种界面 手指快速滑动右边滑动条时 可以显示相应的字母图标 android里提供了android.widget.SectionIndexer这个接口去实现该效果 可是只能显示字母 ...

  5. 星座物语APP

    效果图: 这里的后台管理用的是duducat,大家可以去百度看说明.图片,文字都在duducat后台服务器上,可以自己修改的.(PS:图片这里是随便找的) http://www.duducat.com ...

  6. Android静态图片人脸识别的完整demo(附完整源码)

    Demo功能:利用android自带的人脸识别进行识别,标记出眼睛和人脸位置.点击按键后进行人脸识别,完毕后显示到imageview上. 第一部分:布局文件activity_main.xml < ...

  7. Android Drawable之getIntrinsicWidth()和getIntrinsicHeight()

              在Android的开发中,凡是需要画图的地方大都离不开类Drawable.Android的官方文档中介绍这个类就是被设计用来表示可以被画的东西.A Drawable is a ge ...

  8. Drawable: getIntrinsicWidth()和getIntrinsicHeight()方法的使用误区

    经常会使用上述两个API来获取ImageView中显示图片的大小,但是在某些情况下,这两个API返回的大小可能与原图的大小不一致,比如原图大小是72*72,分别把原图放置在xhdpi,xxhdpi,x ...

  9. Android Drawable 那些不为人知的高效用法

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/43752383,本文出自:[张鸿洋的博客] 1.概述 Drawable在我们平时的 ...

随机推荐

  1. ueditor 编辑器上传到服务器后图片上传不能正常使用

    网站集成ueditor编辑器后在本地能正常使用,上传到服务器上后,图片上传功能提示:后端配置项没有正常加载,上传插件不能正常使用.且单个图片上传图标是灰色的不能点击. 相信遇到这个问题的同学是很多的吧 ...

  2. GO语言Windows下Liteide

    今天用到了. 就学习一下. https://www.golangtc.com/t/56e7caf5b09ecc66b90000fe 在网上看了好多此类介绍,操作太麻烦,自己琢磨出来怎么配置了. 以Li ...

  3. java SE :文件基本处理 File、FileFilter、FileNameFilter

    File    对目录及文件的创建.重命名.删除.文件列表.判断是否存在 构造函数 // 完整的目录或文件路径 public File(String pathname) //父级目录/文件路径+子级目 ...

  4. centos7 修改时区

    Linux 系统(我特指发行版, 没说内核) 下大部分软件的风格就是不会仔细去考虑向后 的兼容性, 比如你上个版本能用这种程序配置, 没准到了下一个版本, 该程序已经不见了. 比如 sysvinit ...

  5. yum使用

    一.使用yum安装和卸载软件,有个前提是yum安装的软件包都是rpm格式的.安装的命令是,yum install ~,yum会查询数据库,有无这一软件包,如果有,则检查其依赖冲突关系,如果没有依赖冲突 ...

  6. javascript 进制转换(2进制、8进制、10进制、16进制之间的转换)

    //十进制转其他 var x=110; alert(x); alert(x.toString(8)); alert(x.toString(32)); alert(x.toString(16)); // ...

  7. Android之 服务(1)

    1 简介 服务是Android四大组件之一.不过与Activity不同的是,服务不会直接与用户交互,而是摸摸地在后台运行. 有两种方式来启动系统服务. 一种是调用 Context.startServi ...

  8. navicat for mysql 快捷键

    1.ctrl+q           打开查询窗口2.ctrl+/            注释sql语句3.ctrl+shift +/  解除注释4.ctrl+r           运行查询窗口的s ...

  9. HDU 6201 transaction transaction transaction(树形DP)

    transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 132768/1 ...

  10. iOS 9音频应用播放音频之iOS 9音频播放进度

    iOS 9音频应用播放音频之iOS 9音频播放进度 iOS 9音频应用开发播放进度 音频文件在播放后经过了多久以及还有多久才可以播放完毕,想必是用户所关注的问题.为了解决这一问题,在很多的音乐播放器中 ...