android中恶心的getDrawingCache

1、更新View的Bitmap问题:http://hi.baidu.com/cmdmac/item/b9a822f87aa8171ba62988aa

   最近要写一个可调整listviewitem的listview,当用户按下listitem的某个区域时,可以上下拖动item并放下时调整listitem的位置。在里面用了getDrawingCache来获取按下的listitem相应的bitmap并放在一个创建的ImageView中,然后在move的时移动ImageView。但发现即使调整的listItem的位置,按下时得到的bitmap也是原来的listitem的bitmap.进行了各种调试也没找到问题所在。最后在一个测试工程中调用了setDrawingCacheEnabled(false)后再setDrawingCacheEnabled(true)发现才能获取到更新后的bitmap!实在是没有想到是要这么做的!

2、getDrawingCache()==null解决:http://zartzwj.iteye.com/blog/1098839

   上一篇是讲到如何将view映射成bitmap,但是在使用的时候有时候会出现getDrawingCache()返回的结果是null而NullPointException的异常,我尝试了很多种方式去寻找问题,在buildDrawingCache()的时候得到的结果就是null了,后通过debug源码找到了问题的原因。

      在android.view.View中,有一个方法是buildDrawingCache(boolean autoScale),这个方法是在getDrawingCache()方法或者是在调用buildDrawingCache()时会被调用,在这个方法中有几段代码是这样的:

if (width <= 0 || height <= 0 ||
                     // Projected bitmap size in bytes
         (width * height * (opaque && !translucentWindow ? 2 : 4) >
                 ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize())) {
                destroyDrawingCache();
                return;
  }


在上面的代码中,width和height是所要cache的view绘制的宽度和高度,所以(width * height * (opaque && !translucentWindow ? 2 : 4) 计算的是当前所需要的cache大小。

 

        ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize()得到的是系统所提供的最大的DrawingCache的值。所以我在debug时捕获到的null的原因就是:所需要的drawingCache >系统所提供的最大DrawingCache值。

 

        所以在只需要修改所需的cache值就可以解决问题了,而且也可以修改drawingCacheBackgroundColor的值来适当减少所需的cache值,在上面代码中的opaque值就是格局drawingCacheBackgroundColor来得到的,所以可以控制(opaque && !translucentWindow ? 2 : 4)的值,使之为2就能将cache值减小一半。

 

       现在来说说如何知道系统所能提供的最大DrawingCache值,也就是ScaledMaximumDrawingCacheSize的值的大小。

 

       Android提供了一种比较简单的方式来计算:就是用将当前屏幕的分辨率的高和宽相乘,然后再乘以4就可以得到了ScaledMaximumDrawingCacheSize值了。例如:屏幕分辨率为:320*480,所以ScaledMaximumDrawingCacheSize=324*480*4;

 

       因为我之前调试的时候一直使用android 1.5,所以所提供的屏幕分辨率最大为320*480,所以就会出现getDrawingCache()=null了。现在知道问题之所在,就知道怎么解决了。

 

 

       如有问题,请留言,会尽快恢复。

一个好的解决方案是:

public static Bitmap convertViewToBitmap(View view){
      view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
        view.buildDrawingCache();
        Bitmap bitmap = view.getDrawingCache();

     return bitmap;
}


3、比较全的解决办法:http://www.cnblogs.com/devinzhang/archive/2012/06/05/2536848.html

  

1.前言

  Android中经常会遇到把View转换为Bitmap的情形,比如,对整个屏幕视图进行截屏并生成图片;Coverflow中需要把一页一页的view转换为Bitmap、以便实现复杂的图形效果(阴影、倒影效果等);再比如一些动态的实时View为便于观察和记录数据、需要临时生成静态的Bitmap。

2.实现方法

  1)下面是笔者经常用的一个转换方法

public static Bitmap convertViewToBitmap(View view, int bitmapWidth, int bitmapHeight){
        Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
        view.draw(new Canvas(bitmap));
        
        return bitmap;
    }


或者用如下方法:

public static Bitmap convertViewToBitmap(View view){
       view.buildDrawingCache();
    Bitmap bitmap = view.getDrawingCache();
    return bitmap; 
}

一般情况下,这个方法能够正常的工作。但有时候,生成Bitmap会出现问题(Bitmap全黑色)。主要原因是drawingCache的值大于系统给定的值。我们可以看一下buildDrawingCache()方法中的一段代码:

 

if (width <= 0 || height <= 0 ||(width * height * (opaque && !translucentWindow ? 2 : 4) > ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize())) {   
                 destroyDrawingCache();   
                 return;   
  }  


上面的代码中,width和height是所要cache的view绘制的宽度和高度,所以(width * height * (opaque && !translucentWindow ? 2 : 4) 计算的是当前所需要的cache大小。ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize()得到的是系统所提供的最大的DrawingCache的值。当所需要的drawingCache >系统所提供的最大DrawingCache值时,生成Bitmap就会出现问题,此时获取的Bitmap就为null。

        所以在只需要修改所需的cache值就可以解决问题了。于是我们引入第二种方法:

 

  2)完美的解决方案

public static Bitmap convertViewToBitmap(View view){
      view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
        view.buildDrawingCache();
        Bitmap bitmap = view.getDrawingCache();

     return bitmap;
}


view 使用 "getMeasuredWidth()" and "getMeasuredHeight()"方法计算长宽。此时,Bitmap就能正确获取了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值