Android图片加载框架Picasso最全使用教程 三
2016-11-29 16:27
567 查看
前面我们对Picasso的用法有了一定得了解,下面就分析一下一些特殊情况下,Picasso的用法.
Picasso的默认图片加载方式有一个淡入的效果,如果调用了
2
3
4
5
6
7
1
2
3
4
5
6
7
有一个场景,当你从网上加载了一张图片到
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
如果图片很大或者想自定义图片的显示样式,可以调用该API来解决这个问题;
2
3
4
5
1
2
3
4
5
如果我们调用了
2
3
4
5
6
1
2
3
4
5
6
如果图片被操作了,可能在展示的时候就会比较丑,我们是想改变这种情景的,Picasso给我们提供了两种选择进行图片展示,
Inside()
2
3
4
5
6
1
2
3
4
5
6
如果调用了该API, Picasso会对图片的大小及
2
3
4
5
1
2
3
4
5
如果一个屏幕上顶部图片较大,而底部图片较小,因为Picasso是异步加载,所以小图会先加载出来,但是对于用户来说,更希望看到的是上面的图片先加载,底部的图片后加载,Picasso支持设置优先级,分为
和
2
3
4
5
6
1
2
3
4
5
6
注意:设置优先级并不能保证图片就一定会被优先加载,只是会偏向倾斜于先加载;
我们都知道,在一个
Picasso提供了三种设置Tag的方式
暂停标记
可见标记
取消标记
在图片请求时添加标记
2
3
4
5
1
2
3
4
5
然后让
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
试想一下,当你在浏览购物车的时候,这个时候就会去展示所有被选中item的图片资源,如果这个时候用户点击了购买按钮,就会弹出一个
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
注意:如果tag状态为pause或者resume的话,Picasso会对tag持有一个引用,如果此时用户退出了当前
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
注意:你可以使用
Picasso有一个功能是可以加载图片到
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
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
上面可以看到,Picasso的使用也是非常简单,只需要调用
效果如下
调用.noFade()
Picasso的默认图片加载方式有一个淡入的效果,如果调用了noFade(),加载的图片将直接显示在
ImageView上
Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .placeholder(R.mipmap.ic_launcher) .error(R.mipmap.future_studio_launcher) .noFade() .into(imageViewFade);1
2
3
4
5
6
7
1
2
3
4
5
6
7
调用.noPlaceholder()
有一个场景,当你从网上加载了一张图片到Imageview上,过了一段时间,想在同一个
ImageView上展示另一张图片,这个时候你就会去调用Picasso,进行二次请求,这时Picasso就会把之前的图片进行清除,可能展示的是
.placeholder()的图片,给用户并不是很好的体验,如果调用了
noPlaceholder(),就不会出现这种情况.
Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .placeholder(R.mipmap.ic_launcher) .into(imageViewNoPlaceholder, new Callback() { @Override public void onSuccess() { // 当上次加载完成后,进行二次加载 Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[1]) .noPlaceholder() .into(imageViewNoPlaceholder); } @Override public void onError() { } });1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
调用resize(x, y)
来自定义图片的加载大小
如果图片很大或者想自定义图片的显示样式,可以调用该API来解决这个问题;Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .resize(600, 200) .into(imageViewResize);1
2
3
4
5
1
2
3
4
5
调用`onlyScaleDown()来缩短图片的加载计算时间
如果我们调用了resize(x,y)方法的话,Picasso一般会重新计算以改变图片的加载质量,比如一张小图变成一张大图进行展示的时候,但是如果我们的原图是比我们从新resize的新图规格大的时候,我们就可以调用
onlyScaleDown()来直接进行展示而不再重新计算.
Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .resize(6000, 2000) .onlyScaleDown() // 如果图片规格大于6000*2000,将只会被resize .into(imageViewResizeScaleDown);1
2
3
4
5
6
1
2
3
4
5
6
对拉伸图片的处理
如果图片被操作了,可能在展示的时候就会比较丑,我们是想改变这种情景的,Picasso给我们提供了两种选择进行图片展示,centerCrop()或者
centerInside().
centerCrop()- 图片会被剪切,但是图片质量看着没有什么区别
Inside()
- 图片会被完整的展示,可能图片不会填充满ImageView`,也有可能会被拉伸或者挤压
Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .resize(600, 200) .centerInside() 或者调用 .centerCrop() .into(imageViewResizeCenterInside);1
2
3
4
5
6
1
2
3
4
5
6
调用.fit()
来智能展示图片
如果调用了该API, Picasso会对图片的大小及ImageView进行测量,计算出最佳的大小及最佳的图片质量来进行图片展示,减少内存,并对视图没有影响;
Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .fit() .into(imageViewHero);1
2
3
4
5
1
2
3
4
5
调用.priority()
设置图片加载的优先级
如果一个屏幕上顶部图片较大,而底部图片较小,因为Picasso是异步加载,所以小图会先加载出来,但是对于用户来说,更希望看到的是上面的图片先加载,底部的图片后加载,Picasso支持设置优先级,分为HIGH,
MEDIUM,
和
LOW,所有的加载默认优先级为
MEDIUM;
Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .fit() .priority(Picasso.Priority.HIGH) .into(imageViewHero);1
2
3
4
5
6
1
2
3
4
5
6
注意:设置优先级并不能保证图片就一定会被优先加载,只是会偏向倾斜于先加载;
调用tag()
为请求添加标记提升用户体验
我们都知道,在一个ListView的子
item中加载一张图片是很常见的,这些图片都来源于网络请求,如果这个
listview有上千条数据,当用户快速滑动的时候,每个item会不断的被复用,当然Picasso的请求也不断地进行请求,取消请求,再次请求,再次取消的操作(对屏幕外的自动取消请求),但是如果有一个方案,可以在用户在快速滑动的时候全部停止请求,只有在滑动停止时再去请求,就非常完美了;
Picasso提供了三种设置Tag的方式
暂停标记
pauseTag()
可见标记
resumeTag()
取消标记
cancleTag()
pauseTag()
和 resumeTag()
的用法
在图片请求时添加标记Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .tag("Profile ListView") //参数为 Object .into(imageViewWithTag);1
2
3
4
5
1
2
3
4
5
然后让
listview实现滑动监听
@Override public void onScrollStateChanged(AbsListView view, int scrollState) { final Picasso picasso = Picasso.with(context); if (scrollState == SCROLL_STATE_IDLE || scrollState == SCROLL_STATE_TOUCH_SCROLL) { picasso.resumeTag("Profile ListView"); } else { picasso.pauseTag("Profile ListView"); } }1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
cancleTag()
的使用场景
试想一下,当你在浏览购物车的时候,这个时候就会去展示所有被选中item的图片资源,如果这个时候用户点击了购买按钮,就会弹出一个progressdialog去请求数据以进行页面跳转,这个时候原来的请求就需要取消掉了;
public void buyButtonClick(View v) { showDiaolg(); // 取消网络请求 Picasso .with(context) .cancelTag("ShoppingCart"); }1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
注意:如果tag状态为pause或者resume的话,Picasso会对tag持有一个引用,如果此时用户退出了当前
Activity,垃圾回收机制进行回收的时候,就会出现内存泄露,所以需要在
onDestory()方法中进行相应处理;
.fetch()
, .get()
及 Target
之间的区别
.fetch()- 该方法会在后台异步加载一张图片,但是不会展示在
ImageView上,也不会返回
Bitmap,这个方法只是为了将获取到的资源加载到本地和内存中,为了后期加载缩短时间;
.get()- 该方法也是一个异步线程,不过加载完成后会返回一个
Bitmap,但是需要注意,该方法不能在主线程中调用,因为会造成线程阻塞;
Target- 我们之前调用
.into()方法,只是将获取到的资源加载到
ImageView中,但我们还可以将资源作为回调放到
Target中,上代码:
private Target target = new Target() { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { //加载成功后会得到一个bitmap,可以自定义操作 } @Override public void onBitmapFailed(Drawable errorDrawable) { // 加载失败进行相应处理 } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { } }; Picasso .with(context) .load(UsageExampleListViewAdapter.eatFoodyImages[0]) .into(target);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
注意:你可以使用
.get()或者
Target获取图片的
Bitmap,但是当你使用
Target时,不能使用匿名内部类的方式,因为垃圾回收机制在你获取不到
Bitmap的时候会把对象回收;
Picasso在自定义Notifications
上的使用
Picasso有一个功能是可以加载图片到RemoteViews上,而
RemoteViews是用在
Widgets及自定义
notification布局上的,下面通过一个小的示例来看Picasso是如何起作用的;
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); }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
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
上面可以看到,Picasso的使用也是非常简单,只需要调用
.into()的另一个重载方法即可:
.into(Android.widget.RemoteViews remoteViews, int viewId, int notificationId, android.app.Notification notification)
效果如下
相关文章推荐
- Android图片加载框架Picasso最全使用教程 一
- Android图片加载框架Picasso最全使用教程
- Android图片加载框架Picasso最全使用教程 二
- Android图片加载框架Picasso最全使用教程 三
- Android图片加载框架Picasso最全使用教程 四
- Android图片加载框架Picasso最全使用教程 五
- Android图片加载框架Picasso最全使用教程 一
- Android图片加载框架Picasso最全使用教程 二
- Android图片加载框架Picasso最全使用教程1
- Android图片加载框架Picasso最全使用教程2
- Android图片加载框架Picasso最全使用教程3
- Android图片加载框架Picasso最全使用教程4
- Android图片加载框架Picasso最全使用教程5
- Android图片加载框架Picasso最全使用教程 一
- Android图片加载框架Picasso最全使用教程 二
- Android图片加载框架Picasso最全使用教程 三
- Android图片加载框架Picasso最全使用教程 四
- Android图片加载框架Picasso最全使用教程 五
- Android图片加载框架Picasso使用教程 (二)listviewh和gridview
- Android图片加载框架Picasso使用教程 (三)