Android进阶BitmapAndroid开发

Glide高级用法

2017-08-25  本文已影响368人  慕涵盛华

目录

简介

Glide是面向Android的快速高效的开源媒体管理和图像加载框架,将媒体解码,内存和磁盘缓存以及资源池融合到一个简单易用的界面中。
Glide支持获取,解码和显示视频静止图像,图像和动画GIF。Glide包括一个灵活的API,允许开发人员几乎可以插入任何网络堆栈。默认情况下,Glide使用基于自定义HttpUrlConnection的堆栈,而且还包括实用程序库插入到Google的Volley项目或Square的OkHttp库。
Glide的主要重点是尽可能平滑和快速地滚动任何类型的图像列表,但是对于几乎任何需要获取,调整大小和显示远程图像的情况,Glide也是有效的。

说明:Glide默认使用HttpUrlConnection来加载网络图片,如果你应用中添加了OkHttp,Glide会自动合并使用Okhttp来加载网络图片,同理也支持Volley。如果同时添加了这两个网络依赖库,那这两个库都会被添加。因为 Glide 没有任何特殊的加载顺序,将会有一个不稳定的状态,它并不明确使用哪个网络库,所以确保只添加一个集成库。

使用Demo

//先获取缩略图
DrawableRequestBuilder<String> thumbnailRequest = Glide
            .with(context)
            .load(picture.getSmall())
            .bitmapTransform(new BlurTransformation(context, 5),//模糊转换
                    new TopCropTransformation(context));


DrawableRequestBuilder<String> pictureRequest = Glide
            .with(context)
            .load(picture.getMiddle())
            .thumbnail(thumbnailRequest) //缩略图
            .placeholder(R.drawable.image_holder_goods)
            .error(R.drawable.ic_loading_failure_big)
            .dontAnimate()
            .diskCacheStrategy(DiskCacheStrategy.ALL)
            .bitmapTransform(new TopCropTransformation(context))
            .into(imageview);

效果图

效果图

API说明

占位图,imgUrl加载时显示的图片

imgUrl加载失败时显示的图片

使用标准的淡入淡出动画显示图片

直接显示图片而没有任何淡入淡出效果

在图片显示到 ImageView之前重新改变图片大小。(明确指定图片大小)

缩放图像让它填充到 ImageView 界限内并且裁剪额外的部分。ImageView 可能会完全填充,但图像可能不会完整显示。

裁剪图片,即缩放图像让图像都测量出来等于或小于 ImageView 的边界范围。该图像将会完全显示,但可能不会填满整个 ImageView。

如果imgUrl是一个 gif,跟之前的用法没有区别;如果这个 imgUrl 不是一个 gif,Glide 将会把这个 load 当成失败处理。这样做的的好处是:.error() 被调用并且错误占位符被显示,即使 imgUrl 是一个普通的的图片

在某些情况下,如果你仅仅想要显示 Gif 的第一帧,你可以调用 asBitmap() 去保证其作为一个常规的图片显示,即使这个 URL 是一个 gif。

自定义变换动画

Priority.LOW :最低
Priority.NORMAL :正常
Priority.HIGH :高
Priority.IMMEDIATE :立即显示

使用场景:你的 App 将会需要在同一时间内加载多个图像。让我们假设你正在构建一个信息屏幕,这里有一张很大的图片在顶部,还有两个小的,在底部还有一些不那么重要的图片。对于最好的用户体验来说,应该先显示顶部大的图片,然后才是底部不紧急的 图片

Glide缓存

Glide 不仅仅缓存一张图片,而是缓存了原始图像,全分辨率图像和另外小版本的图像。例如:如果你请求的一个图像是 1000x1000 像素的,但你的 ImageView 是 500x500 像素的,Glide 将会把这两个尺寸都进行缓存。

设置 Glide 跳过内存缓存,也就是说这张图片不在做内存缓存,但依然做磁盘缓存。
注意:对于相同的 URL ,如果初始请求没调用 .skipMemoryCache(true) 方法,你后来又调用了 .skipMemoryCache(true) 这个方法,这个资源将会在内存中获取缓存。当你想要去调整缓存行为时,确保对同一个资源调用的一致性。

DiskCacheStrategy.NONE 什么都不缓存
DiskCacheStrategy.SOURCE 仅仅只缓存原来的全分辨率的图像。在我们上面的例子中,将会只有一个 1000x1000 像素的图片
DiskCacheStrategy.RESULT 仅仅缓存最终的图像,即:降低分辨率后的(或者是转换后的)
DiskCacheStrategy.ALL 缓存所有版本的图像(默认行为)

Glide缩略图

缩略图不同于占位图。占位图必须是本地图片才行。缩略图是动态占位图。它也可以从网络中加载。缩略图将会在实际请求加载完或者处理完之后才显示。如果缩略图对于任何原因,在原始图像到达之后,它不会取代原始图像。它只会被抹除。Glide提供了两种缩略图方式

使用场景

这个方法在 ListView的组合和详细视图中是非常有用的。例如:在ListView的item中显示的是250x250 像素的图像,然后点击item跳转到详情页面,将在详细视图中需要一个更大的分辨率图像。
从用户的角度来看,他已经看到较小版本的图像,为什么在详情页中出现一个占位符显示了几秒,然后相同图像又再次一次显示(高分辨率的)?
在这种情况下,它有更好的意义去继续显示这张 250x250 像素版本的图像在详情视图上,并且后台去加载全分辨率的图像,然后再显示高清的图片。

第一种

thumbnail(float scale)

第二种

private void loadImageThumbnailRequest() {  

   DrawableRequestBuilder<String> thumbnailRequest = Glide
        .with( context )
        .load( url );

   Glide
        .with( context )
        .load( imgUrl)
        .thumbnail( thumbnailRequest )
        .into( imageView3 );
}

所不同的是,第二种缩略图请求是完全独立于第二个原始请求的。该缩略图可以是不同的资源或图片URL,你可以为其应用不同的转换,等等。

获取Bitmap

Glide 隐藏了一大堆复杂的在后台的场景。Glide 做了所有的网络请求和处理在后台线程中,一旦结果准备好了之后,切回到 UI 线程然后更新 ImageView。如果我们只要 Bitmap 本身。Glide 提供了一个用 Targets 的简单的方式去接受图片资源的 Bitmap。Targets 是没有任何别的回调,它在 Glide 做完所有的加载和处理之后返回结果。

// 如果想获取指定大小的Bitmap,可以在构造方法中指定具体的大小: new SimpleTarget<Bitmap>( 250, 250 )
private SimpleTarget target = new SimpleTarget<Bitmap>() {  
    @Override
    public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
        imageView1.setImageBitmap( bitmap );
    }
};

Glide
    .with( context ) // could be an issue!
    .load( eatFoodyImages[0] )
    .asBitmap()
    .into( target );

注意:

  • 在 Glide 做完图片请求之前, Android 垃圾回收移除了这个匿名内部类对象。最终这可能会导致一个情况,当图像加载完成了,但是回调再也不会被调用。所请确保你所声明的回调对象是作为一个字段对象的,这样就可以保证它避免被垃圾回收机制回收
  • Glide.with(context),这里的问题实际是 Glide 的功能:当你传了一个 context,例如是当前应用的 activity,Glide 将会自动停止请求当请求的 activity 已经停止的时候。这整合到了应用的生命周期中通常是非常有帮助的,但是有时工作起来是困难的,如果你的 target 是独立于应用的 activity 生命周期。这里的解决方案是用 application 的 context: .with(context.getApplicationContext))。当应用完全停止时,Glide 才会杀死这个图片请求。

自定义View

Glide 并不支持加载图片到自定义 view (该自定义View不是继承的ImageView)中,因为并没有方法知道图片应该在哪里被设置。然而,Glide 可以用 ViewTarget 来实现在自定义View中的使用。

private void loadImageViewTarget() {  

  //MyView :自定义View,里面有一个ImageView
  MyView customView = (MyView) findViewById( R.id.custom_view );

  viewTarget = new ViewTarget<MyView, GlideDrawable>( customView ) {
      @Override
      public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
          this.customView.setImage( resource.getCurrent() );
    }
};

  Glide
      .with( context.getApplicationContext() )
      .load( imgUrl )
      .into( viewTarget );
}

图片变换

在图片被显示之前,transformations(转换) 可以被用于图像的操作处理。例如:应用需要显示一个灰色的图像,但是我们只能访问到原始色彩的版本,你可以用 transformation 去操作 bitmap,从而将一个明亮色彩版本的图片转换成灰暗的版本。transformation 不仅限于颜色转换。你可以图片的任意属性:尺寸,范围,颜色,像素位置等等!

你这里你可以使用任何转换,无论它是否是用于图像还是 gif。

它只能用于 bitmap 的转换。

Glide  
  .with( context )
  .load( imgUrl)
  .transform( new BlurTransformation( context ) )//模糊变换
  //.bitmapTransform( new BlurTransformation( context ) ) 
  .into( imageView1 );

添加依赖:'jp.wasabeef:glide-transformations:2.0.1'

注意:当你用了转换后你就不能使用 .centerCrop() 或 .fitCenter() 了。

加载图片到 Notifications

通知栏图标对用户来说是重要的上下文。用 NotificationCompat.Builder 来直接设置通知图片,但是图像必须以 Bitmap 的形式。如果图片是本地的,这很简单。然而,如果图片需要从网上加载的话,使用标准的方式来处理就变得很复杂了。Glide提供了NotificationTarget就变得非常简单了

Glide  
  .with( context.getApplicationContext() )
  .load( eatFoodyImages[3] )
  .asBitmap()
  .into( notificationTarget );

加载图片到App Widgets

应用小部件一直以来都是 Android 的一部分。如果你的 App 提供了小部件并且包含图像,Glide 的AppWidgetTarget 能显著的让你非常简单的实现。

public class MyAppWidgetProvider extends AppWidgetProvider {

    private AppWidgetTarget appWidgetTarget;

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
                     int[] appWidgetIds) {

        RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.custom_view_futurestudio);
        appWidgetTarget = new AppWidgetTarget( context, rv, R.id.custom_view_image, appWidgetIds );
        Glide
            .with( context.getApplicationContext() ) 
            .load( imgUrl )
            .asBitmap()
            .into( appWidgetTarget );
        pushWidgetUpdate(context, rv);
}

    public static void pushWidgetUpdate(Context context, RemoteViews rv) {
        ComponentName myWidget = new ComponentName(context, MyAppWidgetProvider.class);
        AppWidgetManager manager = AppWidgetManager.getInstance(context);
        manager.updateAppWidget(myWidget, rv);
    }
}

其他

参考文章:Glide — Getting Started

关注微信公众号获取更多相关资源


Android小先生
上一篇下一篇

猜你喜欢

热点阅读