Android图片加载与缓存开源框架总结
ImageLoader可以支持图片下载的过程监听,Picasso和Glide都是非常优秀的,而且使用起来非常容易上手,我们站在用户的需求上考虑,若用户要求更完美的展示图片的细节,那么非Picasso莫属,若更注重于顺滑的图片滑动体验Glide更加适合。
ImageLoader其实也不难,下面来看看代码:
下载地址:
http://download.csdn.net/detail/wwj_748/5975847
http://download.csdn.net/detail/wwj_748/5975847
要使用ImageLoader就要到这里下载jar包:
https://github.com/nostra13/Android-Universal-Image-Loader
1.功能概要
Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是提供一个可重复使用的仪器为异步图像加载,缓存和显示。
(1).使用多线程加载图片
(2).灵活配置ImageLoader的基本参数,包括线程数、缓存方式、图片显示选项等;
(3).图片异步加载缓存机制,包括内存缓存及SDCard缓存;
(4).采用监听器监听图片加载过程及相应事件的处理;
(5).配置加载的图片显示选项,比如图片的圆角处理及渐变动画。
2.简单实现
ImageLoader采用单例设计模式,ImageLoader imageLoader = ImageLoader.getInstance();得到该对象,每个ImageLoader采用单例设计模式,ImageLoader必须调用init()方法完成初始化。
- // 1.完成ImageLoaderConfiguration的配置
- ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(this)
- .memoryCacheExtraOptions(480, 800) // default = device screen dimensions
- .discCacheExtraOptions(480, 800, CompressFormat.JPEG, 75, null)
- .taskExecutor(...)
- .taskExecutorForCachedImages(...)
- .threadPoolSize(3) // default
- .threadPriority(Thread.NORM_PRIORITY - 1) // default
- .tasksProcessingOrder(QueueProcessingType.FIFO) // default
- .denyCacheImageMultipleSizesInMemory()
- .memoryCache(new LruMemoryCache(2 * 1024 * 1024))
- .memoryCacheSize(2 * 1024 * 1024)
- .memoryCacheSizePercentage(13) // default
- .discCache(new UnlimitedDiscCache(cacheDir))// default
- .discCacheSize(50 * 1024 * 1024) // 缓冲大小
- .discCacheFileCount(100) // 缓冲文件数目
- .discCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
- .imageDownloader(new BaseImageDownloader(context)) // default
- .imageDecoder(new BaseImageDecoder()) // default
- .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
- .writeDebugLogs()
- .build();
- // 2.单例ImageLoader类的初始化
- ImageLoader imageLoader = ImageLoader.getInstance();
- imageLoader.init(config);
- // 3.DisplayImageOptions实例对象的配置
- // 以下的设置再调用displayImage()有效,使用loadImage()无效
- DisplayImageOptions options = new DisplayImageOptions.Builder()
- .showStubImage(R.drawable.ic_stub) // image在加载过程中,显示的图片
- .showImageForEmptyUri(R.drawable.ic_empty) // empty URI时显示的图片
- .showImageOnFail(R.drawable.ic_error) // 不是图片文件 显示图片
- .resetViewBeforeLoading(false) // default
- .delayBeforeLoading(1000)
- .cacheInMemory(false) // default 不缓存至内存
- .cacheOnDisc(false) // default 不缓存至手机SDCard
- .preProcessor(...)
- .postProcessor(...)
- .extraForDownloader(...)
- .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)// default
- .bitmapConfig(Bitmap.Config.ARGB_8888) // default
- .decodingOptions(...)
- .displayer(new SimpleBitmapDisplayer()) // default 可以设置动画,比如圆角或者渐变
- .handler(new Handler()) // default
- .build();
- // 4图片加载
- // 4.1 调用displayImage
- imageLoader.displayImage(
- uri, /*
- String imageUri = "http://site.com/image.png"; // from Web
- String imageUri = "file:///mnt/sdcard/image.png"; // from SD card
- String imageUri = "content://media/external/audio/albumart/13"; // from content provider
- String imageUri = "assets://image.png"; // from assets
- */
- imageView, // 对应的imageView控件
- options); // 与之对应的image显示方式选项
- // 4.2 调用loadImage
- // 对于部分DisplayImageOptions对象的设置不起作用
- imageLoader.loadImage(
- uri,
- options,
- new MyImageListener()); //ImageLoadingListener
- class MyImageListener extends SimpleImageLoadingListener{
- @Override
- public void onLoadingStarted(String imageUri, View view) {
- imageView.setImageResource(R.drawable.loading);
- super.onLoadingStarted(imageUri, view);
- }
- @Override
- public void onLoadingFailed(String imageUri, View view,
- FailReason failReason) {
- imageView.setImageResource(R.drawable.no_pic);
- super.onLoadingFailed(imageUri, view, failReason);
- }
- @Override
- public void onLoadingComplete(String imageUri, View view,
- Bitmap loadedImage) {
- imageView.setImageBitmap(loadedImage);
- super.onLoadingComplete(imageUri, view, loadedImage);
- }
- @Override
- public void onLoadingCancelled(String imageUri, View view) {
- imageView.setImageResource(R.drawable.cancel);
- super.onLoadingCancelled(imageUri, view);
- }
- }
3.支持的Uri
- String imageUri = "http://site.com/image.png"; // from Web
- String imageUri = "file:///mnt/sdcard/image.png"; // from SD card
- String imageUri = "content://media/external/audio/albumart/13"; // from content provider
- String imageUri = "assets://image.png"; // from assets
- String imageUri = "drawable://" + R.drawable.image; // from drawables (only images, non-9patch)
加载drawables下图片,可以通过ImageView.setImageResource(...) 而不是通过上面的ImageLoader.
4.缓冲至手机
默认不能保存缓存,必须通过下面的方式指定
- DisplayImageOptions options = new DisplayImageOptions.Builder()
- ...
- .cacheInMemory(true)
- .cacheOnDisc(true)
- ...
- .build();
- ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
- ...
- .defaultDisplayImageOptions(options)
- ...
- .build();
- ImageLoader.getInstance().init(config); // Do it on Application start
- ImageLoader.getInstance().displayImage(imageUrl, imageView); /*
- 默认为defaultDisplayImageOptions设定的options对象,此处不用指定options对象 */
或者通过下面这种方式
- DisplayImageOptions options = new DisplayImageOptions.Builder()
- ...
- .cacheInMemory(true)
- .cacheOnDisc(true)
- ...
- .build();
- ImageLoader.getInstance().displayImage(imageUrl, imageView, options); //此处指定options对象
由于缓存需要在外设中写入数据,故需要添加下面的权限
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
5.OutOfMemoryError
如果OutOfMemoryError错误很常见,可以通过下面的方式设置
(1).减少configuration中线程池的线程数目(.threadPoolSize(...)) 推荐为1 - 5
(2).display options通过.bitmapConfig(Bitmap.Config.RGB_565)设置. Bitmaps in RGB_565 consume 2 times less memory than in ARGB_8888.
(3).使用configuration的memoryCache(new WeakMemoryCache())方法 或者不调用.cacheInMemory()方法
(4).display options通过.imageScaleType(ImageScaleType.IN_SAMPLE_INT) 或者 .imageScaleType(ImageScaleType.EXACTLY)方法
(4).避免使用RoundedBitmapDisplayer,它创建了一个新的ARGB_8888 Bitmap对象
6.内存缓存管理
通过imageLoaderConfiguration.memoryCache([new LruMemoryCache(1)]))对手机内存缓存进行管理
LruMemoryCache
API >= 9默认.it is moved to the head of a queue.
FreqLimitedMemoryCache
当超过缓存大小后,删除最近频繁使用的bitmap
LRULimitedMemoryCache
API < 9 默认.当超过缓存大小后,删除最近使用的bitmap
FIFOLimitedMemoryCache
FIFO rule is used for deletion when cache size limit is exceeded
LargestLimitedMemoryCache
The largest bitmap is deleted when cache size limit is exceeded
WeakMemoryCache
Unlimited cache
7.SDcard缓存管理
通过imageLoaderConfiguration.discCache([new TotalSizeLimitedDiscCache()]))对SD卡缓存进行管理
UnlimitedDiscCache
default The fastest cache, doesn't limit cache size
TotalSizeLimitedDiscCache
Cache limited by total cache size. If cache size exceeds specified limit then file with themost oldest lastusage date will be deleted
FileCountLimitedDiscCache
Cache limited by file count. If file count in cache directory exceeds specified limit then file with the most oldest last usage date will be deleted.
LimitedAgeDiscCache
Size-unlimited cache with limited files' lifetime. If age of cached file exceeds defined limit then it will be deleted from cache.
UnlimitedDiscCache is 30%-faster than other limited disc cache implementations.
Glide是谷歌推荐使用的加载图片的框架,它相对于其他的框架有更多的有点,说到Glide我们不得不谈谈Picasso,为什么呢?这是因为Picasso的使用与Glide的使用上非常的相似,但是细细看,有明显不同,首先我们看下Picasso与Glide的基本用法?
Picasso:
Picasso.with(this)
.load(url)//加载图片
.placeholder(R.mipmap.ic_launcher)//正在加载时的图片
.error(R.mipmap.ic_launcher)//加载错误是的图片
.into(glide_image2);
Glide:
Glide.with(this)
.load(url)//加载图片
.placeholder(R.mipmap.ic_launcher)//正在加载时的图片
.error(R.mipmap.ic_launcher)//加载错误是的图片
.into(glide_image);
1、看到没有,是不是一样呢,基本上它们的用法一直,但是我们在使用Glide时需要注意,Glide.with(this),我们在传入的时候,我建议传入Actitiy,Fragment对应得context,而不是全局的context,为什么呢,这是因为这样我们可以让Gilde加载图片与我们的Activity,Fragment的生命周期一直,创建时去加载,销毁时停止加载,
2、Glide的加载速度比Picasso的加载速度要快,但是消耗的内存要比Picasso的内存高,为什么呢这是因为Gilde他是根据你传入的尺寸进行缓存,如果俩个地方需要 全尺寸缓存,另一个地方按照比例缓存,那么Glide需要缓存俩次,而Picsso是全尺寸的缓存,每当重新加载时,需要重新绘制
/**
* Glide的全尺寸缓存
*/
public void GlideImage3(String url) {
Glide.with(this)
.load(url)//加载图片
.placeholder(R.mipmap.ic_launcher)//正在加载时的图片
.error(R.mipmap.ic_launcher)//加载错误是的图片
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(glide_image);
}
3,Picasso加载的bitmap格式ARGB_8888而Glide所加载的bitmap格式ARGB_565当然我们可以通过实现GlideMenu来实现
/**
* 更改Glide的bitmap的格式为ARGB_8888
* Created by joe.xiang on 2016/6/9.
*/
public class GlideConfigration implements GlideModule {
@Override
public void applyOptions(Context context, GlideBuilder builder) {
builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
}
@Override
public void registerComponents(Context context, Glide glide) {
}
}
4、Glide的setTag方法不同之处?
我们可以通过在我们的values下建立一个ids的xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="image_tag" type="id"/>
</resources>
通过Image.setTag(R.id.image_tag,url)的形式来进行设置
5、Glide如何设置圆形图片
对于如何制作圆形的方法,有很多可以通过自定义ImageView,当然Glide也给我们提供了很多的方法来时圆角图片。一般有一下方法
1、自定一个Transform 继承 BitmapTransformation
/**
* Created by joe.xiang on 2016/6/9.
*/
public class CircleTransform extends BitmapTransformation {
public CircleTransform(Context context) {
super(context);
}
@Override protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
return circleCrop(pool, toTransform);
}
private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {
if (source == null) return null;
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
// TODO this could be acquired from the pool too
Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
return result;
}
@Override public String getId() {
return getClass().getName();
}
}
/**
* 通过Glide的TransForMation 自定义圆形图片的bitmap
*/
public void RoundImage(String url) {
Glide.with(this)
.load(url)
.asBitmap()
.transform(new CircleTransform(this))
.into(glide_image5);
}
2、我们可以通过BitmapImageVieTarget,来得到一个带圆角的RoundBitmapDrawable;
/**
* 通过RoundBitmapDrawable
*/
public void RoundImage2(String url) {
Glide.with(this)
.load(url)
.asBitmap()
.into(new BitmapImageViewTarget(glide_image6) {
@Override
protected void setResource(Bitmap resource) {
RoundedBitmapDrawable RoundedBitmapDrawable = RoundedBitmapDrawableFactory.create(Glide_1.this.getResources(), resource);
RoundedBitmapDrawable.setCircular(true);
glide_image6.setImageDrawable(RoundedBitmapDrawable);
}
});
3、我们可以通过自定义RoundedCornerLayout 继承RelavityLayout来实现圆角图片效果
**
* Created by joe.xiang on 2016/6/9.
*/
public class RoundedCornerLayout extends RelativeLayout {
private Bitmap maskBitmap;
private Paint paint;
private float cornerRadius;
public RoundedCornerLayout(Context context) {
super(context);
init(context, null, 0);
}
public RoundedCornerLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public RoundedCornerLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs, defStyle);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
setWillNotDraw(false);
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
if (maskBitmap == null) {
// This corner radius assumes the image width == height and you want it to be circular
// Otherwise, customize the radius as needed
cornerRadius = canvas.getWidth() / 2;
maskBitmap = createMask(canvas.getWidth(), canvas.getHeight());
}
canvas.drawBitmap(maskBitmap, 0f, 0f, paint);
}
private Bitmap createMask(int width, int height) {
Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(mask);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE); // TODO set your background color as needed
canvas.drawRect(0, 0, width, height, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, paint);
return mask;
}
}
<huanxin.exmaple.com.android_glidedemo.RoundedCornerLayout
android:layout_width="200dp"
android:layout_height="200dp">
<ImageView
android:id="@+id/glide_image7"
android:layout_width="200dp"
android:layout_height="200dp"
android:scaleType="centerCrop"
/>
</huanxin.exmaple.com.android_glidedemo.RoundedCornerLayout>
使用上跟一般使用没什么区别。。。。。
4 、当然我们亦可以使用开源的圆角图片的自定义控件?
Glide.with(this).load(url).into(new SimpleTarget<GlideDrawable>() {
@Override
public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
//使用自定义的圆角图片
}
});
对于Glide加载图片还有很多可以去研究的地方,它还可以加载gif的动态图,不过这个方法要谨慎使用,因为这个非常耗内存,对于Glide的使用花了一个下午对于他的一些基本使用就总结导致,过段时间深入研究后在总结了、一下附上加载的图片效果图。
Android Glide
Android Glide是一个开源的图片加载和缓存处理的第三方框架。和Android的Picasso库类似,个人感觉比Android Picasso好用。Android Glide使自身内部已经实现了缓存策略,使得开发者摆脱Android图片加载的琐碎事务,专注逻辑业务的代码。Android Glide使用便利,短短几行简单明晰的代码,即可完成大多数图片从网络(或者本地)加载、显示的功能需求。
使用Android Glide,需要先下载Android Glide的库,Android Glide在github上的项目主页:
https://github.com/bumptech/glide 。
实际的项目使用只需要到Glide的releases页面把jar包下载后导入到本地的libs里面即可直接使用。Glide的releases的页面地址:https://github.com/bumptech/glide/releases ,在此页面找到最新的jar包,下载后放到自己项目的libs中,比如glide 3.6.0库的jar包下载地址:https://github.com/bumptech/glide/releases/download/v3.6.0/glide-3.6.0.jar
接下来是在自己的项目中具体使用,现在给出一个具体的使用例子加以简单说明(通过网络加载图片然后在ImageView中显示出来):
MainActivity.java
下载地址:
http://download.csdn.net/detail/shenggaofei/9613805
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
import
com.bumptech.glide.Glide;
import
android.support.v7.app.ActionBarActivity;
import
android.view.LayoutInflater;
import
android.view.View;
import
android.view.ViewGroup;
import
android.widget.ArrayAdapter;
import
android.widget.ImageView;
import
android.widget.ListView;
import
android.app.Activity;
import
android.content.Context;
import
android.os.Bundle;
public
class
MainActivity
extends
ActionBarActivity {
private
Activity mActivity;
// 将从此URL加载网络图片。
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
mActivity =
this
;
setContentView(R.layout.activity_main);
ListView lv = (ListView) findViewById(R.id.listView);
lv.setAdapter(
new
MyAdapter(
this
, R.layout.item));
}
private
class
MyAdapter
extends
ArrayAdapter {
private
int
resource;
public
MyAdapter(Context context,
int
resource) {
super
(context, resource);
this
.resource = resource;
}
@Override
public
View getView(
int
position, View convertView, ViewGroup parent) {
if
(convertView ==
null
) {
convertView = LayoutInflater.from(mActivity).inflate(resource,
null
);
}
ImageView iv = (ImageView) convertView.findViewById(R.id.imageView);
Glide.with(mActivity).load(img_url).centerCrop()
/*
* 缺省的占位图片,一般可以设置成一个加载中的进度GIF图
*/
.placeholder(R.drawable.loading).crossFade().into(iv);
return
convertView;
}
@Override
public
int
getCount() {
// 假设加载的数据量很大
return
10000
;
}
}
}
|
MainActivity.java需要的两个布局文件:
activity_main.xml
1
2
3
4
5
6
|
<linearlayout android:layout_height=
"match_parent"
android:layout_width=
"match_parent"
android:orientation=
"vertical"
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<listview android:id=
"@+id/listView"
android:layout_height=
"wrap_content"
android:layout_width=
"match_parent"
>
</listview>
</linearlayout>
|
item.xml
1
2
3
4
5
6
|
<!--?xml version=
"1.0"
encoding=
"utf-8"
?-->
<linearlayout android:layout_height=
"match_parent"
android:layout_width=
"match_parent"
android:orientation=
"vertical"
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<imageview android:id=
"@+id/imageView"
android:layout_height=
"wrap_content"
android:layout_width=
"wrap_content"
>
</imageview></linearlayout>
|
Android Picasso加载网络图片等比例缩放
下载地址:
http://download.csdn.net/my
在做Android图片加载的时候,由于手机屏幕受限,很多大图加载过来的时候,我们要求等比例缩放,比如按照固定的宽度,等比例缩放高度,使得图片的尺寸比例得到相应的缩放,但图片没有变形。显然按照android:scaleType不能实现,因为会有很多限制,所以必须要自己写算法。
之前也写过一篇文章Android根据屏幕宽度缩放图片,但这是缩放的本地图片,网络图片该如何办呢?
通过Picasso来缩放
其实picasso提供了这样的方法。具体是显示Transformation 的transform方法。
1、先获取网络或本地图片的宽高
2、获取需要的目标宽
3、按比例得到目标的高度
4、按照目标的宽高创建新图
<code class="hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span style="font-size:18px;">Transformation transformation = new Transformation() {
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@Override</span>
public Bitmap transform(Bitmap <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> targetWidth = mImg.getWidth();
LogCat.i(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"source.getHeight()="</span>+<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>.getHeight()+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">",source.getWidth()="</span>+<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>.getWidth()+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">",targetWidth="</span>+targetWidth);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>.getWidth()==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>){
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>;
}
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//如果图片小于设置的宽度,则返回原图</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>.getWidth()<targetWidth){
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>;
}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//如果图片大小大于等于设置的宽度,则按照设置的宽度比例来缩放</span>
double aspectRatio = (double) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>.getHeight() / (double) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>.getWidth();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> targetHeight = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>) (targetWidth * aspectRatio);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (targetHeight != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> && targetWidth != <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>) {
Bitmap result = Bitmap.createScaledBitmap(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>, targetWidth, targetHeight, false);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (result != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>) {
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Same bitmap is returned if sizes are the same</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>.recycle();
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> result;
} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">source</span>;
}
}
}
<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@Override</span>
public String key() {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"transformation"</span> + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">" desiredWidth"</span>;
}
};</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">1</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">2</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">3</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">4</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">5</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">6</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">7</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">8</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">9</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">10</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">11</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">12</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">13</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">14</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">15</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">16</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">17</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">18</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">19</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">20</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">21</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">22</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">23</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">24</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">25</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">26</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">27</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">28</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">29</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">30</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">31</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">32</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">33</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">34</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">35</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">36</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">37</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">38</span></li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">1</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">2</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">3</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">4</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">5</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">6</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">7</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">8</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">9</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">10</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">11</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">12</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">13</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">14</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">15</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">16</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">17</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">18</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">19</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">20</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">21</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">22</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">23</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">24</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">25</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">26</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">27</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">28</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">29</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">30</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">31</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">32</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">33</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">34</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">35</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">36</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">37</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">38</span></li></ul>
之后在Picasso设置transform
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span style="font-size:18px;"> Picasso<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.with</span>(mContext)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.load</span>(imageUrl)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.placeholder</span>(R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.mipmap</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.zhanwei</span>)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.error</span>(R<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.mipmap</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.zhanwei</span>)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.transform</span>(transformation)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.into</span>(viewHolder<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.mImageView</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">1</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">2</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">3</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">4</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">5</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">6</span></li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">1</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">2</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">3</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">4</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">5</span></li><li style="box-sizing: border-box; padding: 0px 5px;"><span style="font-size:18px;">6</span></li></ul>
参考文献:
http://stackoverflow.com/questions/21889735/resize-image-to-full-width-and-variable-height-with-picasso
http://blog.csdn.net/larryl2003/article/details/6919513
ASimpleCache缓存框架的使用
简述
0.1ASimpleCache可以缓存什么
0.2ASimpleCache有什么特色
(4)支持多进程。
0.3ASimpleCache在Android中的使用场景
1ASimpleCache的使用
1.1缓存字符串
- //缓存
- private ACache mACache;
- mACache = ACache.get(this);
- mACache.put(Constants.KEY_STRING, result);
- String result = mACache.getAsString(Constants.KEY_STRING);
- mACache.remove(Constants.KEY_STRING);
1.2缓存JsonObject
- //缓存
- private ACache mACache;
- mACache = ACache.get(this);
- mACache.put(Constants.KEY_JSONOBJECT, jsonObject);
- JSONObject result = mACache.getAsJSONObject(Constants.KEY_JSONOBJECT);
- mACache.remove(Constants.KEY_JSONOBJECT);
1.3缓存JsonArray
- //缓存
- private ACache mACache;
- mACache = ACache.get(this);
- mACache.put(Constants.KEY_JSONARRAY, jsonArray);
- JSONArray result = mACache.getAsJSONArray(Constants.KEY_JSONARRAY);
- mACache.remove(Constants.KEY_JSONARRAY);
1.4缓存Bitmap
- //缓存
- private ACache mACache;
- mACache = ACache.get(this);
- Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
- mACache.put(Constants.KEY_BITMAP, bitmap);
- Bitmap bitmap = mACache.getAsBitmap(Constants.KEY_BITMAP);
- mACache.remove(Constants.KEY_BITMAP);
1.5缓存Drawable
- //缓存
- private ACache mACache;
- mACache = ACache.get(this);
- Drawable drawable = getResources().getDrawable(R.mipmap.ic_launcher);
- mACache.put(Constants.KEY_DRAWABLE, drawable);
- Drawable bitmap = mACache.getAsDrawable(Constants.KEY_DRAWABLE);
- //缓存
- private ACache mACache;
- mACache = ACache.get(this);
- mACache.put(Constants.KEY_JAVA_BEAN, mWeather);
- Weather result = (Weather) mACache.getAsObject(Constants.KEY_JAVA_BEAN);
- mACache.remove(Constants.KEY_JAVA_BEAN);
1.7缓存byte数据
- private ACache mACache;
- mACache = ACache.get(this);
- private void saveByte() {
- OutputStream ostream = null;
- try {
- ostream = mACache.put(Constants.KEY_BYTE);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- if (ostream == null) {
- ToastUtil.simpleToast(this, "Open stream error!");
- return;
- }
- try {
- URL u = new URL(Constants.downloadUrl);
- HttpURLConnection conn = (HttpURLConnection) u.openConnection();
- conn.connect();
- InputStream stream = conn.getInputStream();
- byte[] buff = new byte[1024];
- int counter;
- while ((counter = stream.read(buff)) > 0) {
- ostream.write(buff, 0, counter);
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- // cache update
- ostream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- showTv.setText("done...");
- }
- });
- }
- }
- private void getsByte() {
- InputStream stream = null;
- try {
- stream = mACache.get(Constants.KEY_BYTE);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- if (stream == null) {
- ToastUtil.simpleToast(this, "Bitmap cache is null ...");
- showTv.setText("file not found");
- return;
- }
- try {
- showTv.setText("file size: " + stream.available());
- } catch (IOException e) {
- showTv.setText("error " + e.getMessage());
- }
- }
- mACache.remove(Constants.KEY_BYTE);
觉得不错的话,记得打赏一下: