- 在Adapter中取消了不在视图范围内的ImageView的资源加载,因为可能会产生图片错位;
- 使用复杂的图片转换技术降低内存的使用。
- 自带内存和硬盘的二级缓存机制。
- 内部也是集成LRU(近期最少使用)算法。
static Downloader createDefaultDownloader(Context context) { try { Class.forName("com.squareup.okhttp.OkHttpClient"); return OkHttpLoaderCreator.create(context); } catch (ClassNotFoundException ignored) { } return new UrlConnectionDownloader(context); }
compile 'com.squareup.picasso:picasso:2.5.2'
-dontwarn com.squareup.okhttp.**
Picasso .with(context) .load(imageUrl) .placeholder(R.mipmap.ic_launcher) //添加占位图片 .error(R.mipmap.ic_launcher) //加载失败显示的图片 .into(imageView);
Picasso.with(this).load(userPhotoUrl).into(user_photo, new Callback() { @Override public void onSuccess() { //加载成功 } @Override public void onError() { //加载失败 } });
2.调用.noFade()。Picasso的默认图片加载方式有一个淡入的效果,如果调用了noFade(),加载的图片将直接显示在ImageView上
Picasso .with(context) .load(imageUrl) .placeholder(R.mipmap.ic_launcher) //添加占位图片 .error(R.mipmap.ic_launcher) //加载失败显示的图片 .noFade() // 去除淡入效果 .into(imageView);
3.调用.noPlaceholder()。有一个场景,当你从网上加载了一张图片到Imageview上,过了一段时间,想在同一个ImageView上展示另一张图片,这个时候你就会去调用Picasso,进行二次请求,这时Picasso就会把之前的图片进行清除,可能展示的是.placeholder()的图片,如果你没有设置占位图,则请求的过程中将会是一片空白,给用户并不是很好的体验,如果调用了noPlaceholder(),就不会出现这种情况.
Picasso .with(context) .load(imageUrl) .noPlaceholder(R.mipmap.ic_launcher) //去除占位图 .into(imageView);
Picasso .with(context) .load(imageUrl) .resize(600,200) //自定义图片的加载大小 .into(imageView);
5.调用onlyScaleDown()。一般.resize(x,y)会将加载的图片的重新计算然后按照设定展示出来。如果我们加载的图片的尺寸比.resize(x,y)的尺寸还大,此时调用.onlyScaleDown()将会直接将图片按照.resize(x,y)的尺寸展示出来,效率提高了图片的加载时间。
Picasso .with(context) .load(imageUrl) .resize(600,200) //自定义图片的加载大小 .onlyScaleDown() //效率提高图片的加载时间配合resize(x,y)使用。 .into(imageView);
6.针对拉伸图片的处理。Picasso给我们提供了两种进行图片拉伸的展示方式,视情况选择,避免图片拉伸变形难看。
centerCrop() - 图片会根据最短边进行多余剪切,但是图片质量看着没有什么区别。
Picasso .with(context) .load(imageUrl) .resize(600,200) //自定义图片的加载大小 .centerCrop() //填充居中裁剪显示 .into(imageView);
7.调用.fit()。Picasso会对图片的大小及ImageView进行测量,计算出最佳的大小及最佳的图片质量来进行图片展示,减少内存,并对视图没有影响;
Picasso .with(context) .load(imageUrl) .fit() .into(imageView);
8.调用.priority()。设定图片加载的优先级。通常情况我们进行网络加载图片时一般是哪个图片小就先把那个图片先加载出来。有些时候我们想让图片按照某个顺序或者等级加载图片,Picasso为我们提供了三种图片加载的优先级:HIGH, MEDIUM, LOW。所有的加载默认优先级为MEDIUM。
Picasso .with(context) .load(imageUrl) .fit() .Priority(Picasso.Priority.HIGH) //设定图片加载的优先级 .into(imageView);
9.调用.tag()。控制图片的加载暂停或取消。
Picasso .with(context) .load(imageUrl) .tag("PICASSO_TAG") .into(imageView);
Picasso .with(context) .load(imageUrl) .tag("PICASSO_TAG") .into(imageView);
Picasso .with(context) .cancelTag("PICASSO_TAG");
private void download() { //获得图片的地址 String url = mList.get(mPosition); //Target Target target = new Target(){ @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { String imageName = System.currentTimeMillis() + ".png"; File dcimFile = FileUtil .getDCIMFile(FileUtil.PATH_PHOTOGRAPH,imageName); FileOutputStream ostream = null; try { ostream = new FileOutputStream(dcimFile); bitmap.compress(Bitmap.CompressFormat.PNG, 100, ostream); ostream.close(); } catch (Exception e) { e.printStackTrace(); } Toast.makeText(PicActivity.this,"图片下载至:"+dcimFile,Toast.LENGTH_SHORT).show(); } @Override public void onBitmapFailed(Drawable errorDrawable) { } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { } }; //Picasso下载 Picasso.with(this).load(url).into(target); }
private void testRemoteView() { RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.item_picasso); remoteViews.setImageViewResource(R.id.iv_remoteview, R.mipmap.abc); remoteViews.setTextViewText(R.id.tv_title, "This Title"); remoteViews.setTextViewText(R.id.tv_desc, "This desc"); remoteViews.setTextColor(R.id.tv_title, getResources().getColor(android.R.color.black)); remoteViews.setTextColor(R.id.tv_desc, getResources().getColor(android.R.color.holo_blue_bright)); NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this) .setSmallIcon(R.mipmap.notifation) .setContentTitle("Context Title") .setContentText("Content Text") .setContent(remoteViews) .setPriority(NotificationCompat.PRIORITY_MIN); Notification notification = builder.build(); if (Build.VERSION.SDK_INT > 16) { notification.bigContentView = remoteViews; } NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(NOTIFICATION_ID, notification); Picasso.with(MainActivity.this) .load("http://www.jycoder.com/json/Image/3.jpg") .into(remoteViews, R.id.iv_remoteview, NOTIFICATION_ID, notification); }
12.图片旋转
a.根据自身中心旋转:
Picasso .with(context) .load(imageUrl) .rotate(90f) //旋转90度 .into(imageView);
b.根据某个点旋转:
Picasso .with(context) .load(imageUrl) .rotate(45f, 200f, 100f) //以中心点(200,100)旋转45度。 .into(imageView);
13.Picasso对图片的转化(Transformation扩展)。
先了解一下Transformation这个类,这是一个接口,里面有两个方法,其中transForm这个方法最重要,负责对Bitmap的转换操作。
publicinterface Transformation { //对Bitmap进行转换操作 Bitmap transform(Bitmap source); //一个key 主要是缓存的key的生成和它有关 String key(); }
a.将加载完成的图片做成圆形:
public class CircleTransform implements Transformation { @Override public Bitmap transform(Bitmap source) { //获取最小边长 int size=Math.min(source.getWidth(),source.getHeight()); //获取圆形图片的宽度和高度 int x=(source.getWidth()-size)/2; int y=(source.getHeight()-size)/2; //创建一个正方形区域的Btimap Bitmap squaredBitmap=Bitmap.createBitmap(source,x,y,size,size); if(squaredBitmap!=source){ source.recycle(); } //创建一张可以操作的正方形图片的位图 Bitmap bitmap=Bitmap.createBitmap(size,size,source.getConfig()); //创建一个画布Canvas Canvas canvas=new Canvas(bitmap); //创建画笔 Paint paint=new Paint(); BitmapShader shader=new BitmapShader(squaredBitmap,BitmapShader.TileMode.CLAMP,BitmapShader.TileMode.CLAMP); paint.setShader(shader); paint.setAntiAlias(true); //圆形半径 float r=size/2f; canvas.drawCircle(r,r,r,paint); squaredBitmap.recycle(); return bitmap; } @Override public String key() { return "circle"; } }
调用:
Picasso.with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .transform(new CircleTransform()) .into(imageViewTransformationBlur);
public class BlurTransformation implements Transformation { RenderScript rs; public BlurTransformation(Context context) { super(); rs = RenderScript.create(context); } @Override public Bitmap transform(Bitmap bitmap) { // 创建一个Bitmap作为最后处理的效果Bitmap Bitmap blurredBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); // 分配内存 Allocation input = Allocation.createFromBitmap(rs, blurredBitmap, Allocation.MipmapControl.MIPMAP_FULL, Allocation.USAGE_SHARED); Allocation output = Allocation.createTyped(rs, input.getType()); // 根据我们想使用的配置加载一个实例 ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); script.setInput(input); // 设置模糊半径 script.setRadius(10); //开始操作 script.forEach(output); // 将结果copy到blurredBitmap中 output.copyTo(blurredBitmap); //释放资源 bitmap.recycle(); return blurredBitmap; } @Override public String key() { return "blur"; } }
调用:
Picasso.with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .transform(new BlurTransformation(Context)) .into(imageViewTransformationBlur);
Picasso.with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .transform(new BlurTransformation(Context)) .into(imageViewTransformationBlur);
14.调用.memoryPolicy()。
Picasso .with(context) .load(url) .memoryPolicy(MemoryPolicy.NO_CACHE) .into(imageViewFromDisk);
Picasso .with(context) .load(url) .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE) .into(imageViewFromDisk);
15.调用.networkPolicy()。
Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[2]) .networkPolicy(NetworkPolicy.NO_CACHE) .into(imageViewFromNetwork);
Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[2]) .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE) .networkPolicy(NetworkPolicy.NO_CACHE) .into(imageViewFromNetwork);
16.调用.setIndicatorsEnabled(true),查看图片来源。
Picasso .with(context) .setIndicatorsEnabled(true);
Picasso .with(context) .load(url) .into(imageViewFromDisk);
17.调用.setLoggingEnabled(true)。用来查看每张图片加载出来的用时多少,日志在控制台里打出来。
Picasso .with(context) .setLoggingEngabled(true);
Picasso .with(context) .load(url) .into(imageViewFromDisk);
18.整体加载分析StatsSnapshot。有些时候我们想看我们加载了这么多张图片后图片内存占用多少,可以采用StatsSnapshot.
StatsSnapshot picassoStats = Picasso.with(context).getSnapshot();
Log.d("Picasso Stats", picassoStats.toString());