美文网首页
Glide使用

Glide使用

作者: A_Coder | 来源:发表于2016-11-07 23:55 被阅读0次

    • 在一个 Gradle 项目中在你的 build.gradle中添加下面这行代码:
    compile 'com.github.bumptech.glide:glide:+'
    
    • 从一个 URL 中加载图片
      就像 Picasso, Glide 库是使用流接口(fluent interface)。对一个完整的功能请求,Glide 建造者要求最少有三个参数。
      • with(Context context) - 对于很多 Android API 调用,Context 是必须的。Glide 在这里也一样

      • load(String imageUrl) - 这里你可以指定哪个图片应该被加载,同上它会是一个字符串的形式表示一个网络图片的 URL

      • into(ImageView targetImageView)你的图片会显示到对应的 ImageView 中。

    ImageView targetImageView = (ImageView) findViewById(R.id.imageView);
    String internetUrl = "http://i.imgur.com/DvpvklR.png";
    Glide
           .with(context) 
           .load(internetUrl) 
           .into(targetImageView);
    
    • 从资源中加载图片
    • 从文件中加载
      当你让用户选择一张照片去显示图像(比如画廊)这可能会比较有用。该参数只是一个文件
      对象。
    //这个文件可能不存在于你的设备中。然而你可以用任何文件路径,去指定一个图片路径。
    File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Running.jpg");
    Glide .with(context) .load(file) .into(imageViewFile);
    
    • 从 Uri 中加载图片

    Glide 的一个优势:缓存
    Glide 的缓存实现是基于 Picasso,当加载图片时,Glide 使用3个来源:内存,磁盘和网络(从最快到最慢排序)。

    占位符和渐现动画
    Glide 的流式接口只需要调用 .placeHolder()用一个 drawable(resource) 引用,Glide 将会显示它作为一个占位符,直到你的实际图片准备好。

    Glide 
          .with(context) 
          .load(UsageExampleListViewAdapter.eatFoodyImages[0])
          .placeholder(R.mipmap.ic_launcher) // 也可以是一个drawable 
          .into(imageViewPlaceholder);
    

    不能设置一个网络 url 作为占位符,因为这也会被去请求加载的。App 资源和 drawable 能保证可用和可访问的。然而,作为 load()方法的参数,Glide 接受所有值。

    当App 尝试从一个网站去加载一张图片,但由于某些原因加载失败,使用错误占位符:.error(),在大多数情况下使用占位符,来指明图片不能被加载已经足够了。

    Glide 
        .with(context) 
        .load("http://futurestud.io/non_existing_image.png") 
        .placeholder(R.mipmap.ic_launcher) // 也可以是一个drawable 
        .error(R.mipmap.future_studio_launcher) // 如果图片不能加载就会显示
        .into(imageViewError);
    

    error()接受的参数只能是已经初始化的 drawable 对象或者指明它的资源。

    Glide 使用标准的淡入淡出动画,这是默认激活的。如果你想要如强制 Glide 显示一个淡入淡出动画,你必须调用另外一个建造者:

    Glide 
        .with(context) 
        .load("http://futurestud.io/non_existing_image.png") 
        .placeholder(R.mipmap.ic_launcher) // 也可以是一个drawable 
        .error(R.mipmap.future_studio_launcher) // 如果图片不能加载就会显示
        .
        .into(imageViewError);
    

    crossFade()方法还有另外重载方法 .crossFade(int duration)。如果你想要去减慢(或加快)动画,随时可以传一个毫秒的时间给这个方法。动画默认的持续时间是 300毫秒。

    用 resize(x,y) 调整图片大小
    Glide 自动限制了图片的尺寸在缓存和内存中,并给到 ImageView需要的尺寸。如果图片不会自动适配到 ImageView,调用 override(horizontalSize, verticalSize) 。这将在图片显示到 ImageView之前重新改变图片大小。

    Glide 
        .with(context) 
        .load(UsageExampleListViewAdapter.eatFoodyImages[0])
        .override(600, 200) // 重新改变图片大小成这些尺寸(像素).不关心长宽比
        .into(imageViewResize);
    

    当你还没有目标 view 去知道尺寸的时候,这个选项也可能是有用的。比如,如果 App 想要在闪屏界面预热缓存,它还不能测量 ImageView的尺寸。然而,如果你知道这个图片多少大,用 override 去提供明确的尺寸。

    缩放图像

    • CenterCrop
      CenterCrop()是一个裁剪技术,即缩放图像让它填充到 ImageView
      界限内并且裁剪额外的部分。ImageView可能会完全填充,但图像可能不会完整显示。
    Glide 
        .with(context) 
        .load(UsageExampleListViewAdapter.eatFoodyImages[0]) 
        .override(600, 200) // 重新改变图片大小成这些尺寸(像素)比
        .centerCrop() // 这种裁剪技术缩放图像,使其填充请求的边界,然后裁剪额外的。
        .into(imageViewResizeCenterCrop);
    
    • FitCenter
      fitCenter()是裁剪技术,即缩放图像让图像都测量出来等于或小于 ImageView的边界范围。该图像将会完全显示,但可能不会填满整个 ImageView。
    Glide 
        .with(context) 
        .load(UsageExampleListViewAdapter.eatFoodyImages[0]) 
        .override(600, 200) 
        .fitCenter() 
        .into(imageViewResizeFitCenter);
    

    显示 Gif
    检查图片加载的是否是一个gif图片,调用一个额外的防区强制 Glide变成一个 Gif asGif()

    String gifUrl = "http://i.kinja-img.com/gawker-media/image/upload/s--B7tUiM5l--/gf2r69yorbdesguga10i.gif";
    Glide 
        .with( context ) 
        .load( gifUrl ) 
        .asGif() 
        .error( R.drawable.full_cake ) 
        .into( imageViewGif );
    

    如果这个 gifUrl 不是一个 Gif,.error()回调被调用并且错误占位符被显示。

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

    Glide 
        .with( context ) 
        .load( gifUrl ) 
        .asBitmap() 
        .into( imageViewGifAsBitmap );
    

    内存缓存
    Glide 通过使用默认的内存和磁环缓存去避免不必要的网络请求。调用了 .skipMemoryCache(true)去明确告诉 Glide 跳过内存缓存。可以用 .diskCacheStrategy()方法为 Glide 改变磁盘缓存的行为,如果要为一个请求禁用磁盘缓存。使用枚举 DiskCacheStrategy.NONE。
    作为参数。

    Glide 
        .with( context ) 
        .load( eatFoodyImages[0] ) 
        .diskCacheStrategy( DiskCacheStrategy.NONE ) 
        .skipMemoryCache( true ) 
        .into( imageViewInternet );
    

    Glide 缓存了原始图像,全分辨率图像和另外小版本的图像。对于 .diskCacheStrategy()方法来说不同的枚举参数的意义:

    • DiskCacheStrategy.NONE什么都不缓存
    • DiskCacheStrategy.SOURCE仅仅只缓存原来的全分辨率的图像。
    • DiskCacheStrategy.RESULT仅仅缓存最终的图像,即降低分辨率后的(或者是转换后的)(默认行为
    • DiskCacheStrategy.ALL缓存所有版本的图像

    如果有一张图片,将会经常操作处理,并做了一堆不同的版本,对其有意义的仅仅是缓存原始分辨率图片,用 DiskCacheStrategy.SOURCE。

    图片请求的优先级
    Priority (优先级)枚举

    • Priority.LOW
    • Priority.NORMAL
    • Priority.HIGH
    • Priority.IMMEDIATE

    你正在实现一个信息详情页面,有一个英雄图片在顶部,和较小的图片在底部。对于最好的用户体验来说,英雄图片首先需要被加载。因此,我们用 Priority.HIGH
    来处理它。理论上说,这应该够了,但是为了让这个实例增加点趣味,我们也将底层图像分配给低优先级,用 .priority(Priority.LOW)
    调用:

    private void loadImageWithHighPriority() {
      Glide 
        .with( context ) 
        .load( UsageExampleListViewAdapter.eatFoodyImages[0] ) 
        .priority( Priority.HIGH ) 
        .into( imageViewHero );
    }
    private void loadImagesWithLowPriority() { 
      Glide
        .with( context ) 
        .load( UsageExampleListViewAdapter.eatFoodyImages[1] ) 
        .priority( Priority.LOW ) 
        .into( imageViewLowPrioLeft ); 
      Glide 
        .with( context ) 
        .load( UsageExampleListViewAdapter.eatFoodyImages[2] ) 
        .priority( Priority.LOW ) 
        .into( imageViewLowPrioRight );
    }
    

    缩略图
    用原图的1/10作为缩略图

    Glide 
    .with(this) 
    .load(UsageExampleGifAndVideos.gifUrl) 
    .thumbnail(0.1f) 
    .into(imageView2); 
    

    用其它图片作为缩略图

    
    DrawableRequestBuilder<String> thumbnailRequest = 
        Glide 
          .with(this) 
          .load(R.drawable.news); 
    Glide
        .with(this) 
        .load(UsageExampleGifAndVideos.gifUrl)
        .thumbnail(thumbnailRequest) 
        .into(imageView3);
    

    Glide 中的回调:Targets
    Glide 提供了一个用 Targets的简单的方式去接受图片资源的 Bitmap。Targets 是没有任何别的回调,它在 Glide 做完所有的加载和处理之后返回结果。

    • SimpleTarget:
    private SimpleTarget target2 = new SimpleTarget<Bitmap>(250, 250) { 
        @Override 
        public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) 
        { 
            imageView2.setImageBitmap(bitmap); 
        }
    };
    private void loadImageSimpleTargetApplicationContext() { 
        Glide 
            .with( context.getApplicationContext() ) // 如果你target 是独立于应用的 activity 生命周期,如果请求需要在 activity 生命周期之外去做时,才用这样的代码
            .load(eatFoodyImages[1]) 
            .asBitmap() 
            .into(target2);
    }
    
    • ViewTarget:
      Glide 可以用 ViewTarget加载图片到自定义 view 中。
      首先自定义 View,它继承自 FrameLayout并内部使用了一个 ImageView以及覆盖了一个 TextView。
    public class TargetView extends FrameLayout { 
        ImageView iv; 
        TextView tv; 
        public void initialize(Context context) { 
            inflate(context, R.layout.custom_view_target, this); 
            iv = (ImageView) findViewById(R.id.custom_view_image);
            tv = (TextView) findViewById(R.id.custom_view_text);
        } 
        public TargetView(Context context, AttributeSet attrs) { 
            super(context, attrs); 
            initialize(context); 
        } 
        public TargetView(Context context, AttributeSet attrs, int defStyleAttr) { 
            super(context, attrs, defStyleAttr); 
            initialize( context ); 
        } 
        public void setImage(Drawable drawable) { 
            iv = (ImageView) findViewById( R.id.custom_view_image );         
            iv.setImageDrawable(drawable); 
        }
    }
    

    不能使用常规的 Glide 的方法 .into(),因为我们的自定义 view 并不继承自 ImageView。因此,我们必须创建一个 ViewTarget,并用 .into()方法:

    private void loadImageViewTarget() { 
        TargetView customView = (TargetView) findViewById( R.id.custom_view ); 
        ViewTarget viewTarget = new ViewTarget<TargetView, GlideDrawable>( customView ) { 
            @Override 
            public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) { 
                  this.view.setImage( resource.getCurrent() ); 
            }
         }; 
        Glide 
            .with( context.getApplicationContext() ) // safer! 
            .load( eatFoodyImages[2] ) 
            .into( viewTarget );
    }
    
    • 加载图片到 Notifications(重点)----NotificationTarget
      首先编写通知栏
    <?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content"     
        android:background="@android:color/white" 
        android:orientation="vertical"> 
    
        <LinearLayout 
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:orientation="horizontal" 
        android:padding="2dp">
           <ImageView 
                android:id="@+id/remoteview_notification_icon"     
                android:layout_width="50dp" 
                android:layout_height="50dp"         
                android:layout_marginRight="2dp" 
                android:layout_weight="0" 
                android:scaleType="centerCrop"/> //按比例扩大图片的size居中显示,使得图片长(宽)等于或大于View的长(宽)
          <LinearLayout 
                android:layout_width="0dp" 
                android:layout_height="wrap_content" 
                android:layout_weight="1" 
                android:orientation="vertical"> 
                <TextView 
                    android:id="@+id/remoteview_notification_headline" 
                    android:layout_width="match_parent" 
                    android:layout_height="wrap_content" 
                    android:ellipsize="end"  //内容过长加省略号的属性,省略号在结尾
                    android:singleLine="true"
                    android:textSize="12sp"/> 
              <TextView                 
                    android:id="@+id/remoteview_notification_short_message"                 
                    android:layout_width="match_parent" 
                    android:layout_height="wrap_content" 
                    android:ellipsize="end" 
                    android:paddingBottom="2dp" 
                    android:singleLine="true" 
                    android:textSize="14sp"
                    android:textStyle="bold"/> 
             </LinearLayout> 
        </LinearLayout>
    </LinearLayout> 
    

    创建一个自定义通知

    final RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.remoteview_notification);
    rv.setImageViewResource(R.id.remoteview_notification_icon, R.mipmap.future_studio_launcher);
    rv.setTextViewText(R.id.remoteview_notification_headline, "Headline"); 
    rv.setTextViewText(R.id.remoteview_notification_short_message, "Short Message");// build notification
    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context) 
        .setSmallIcon(R.mipmap.future_studio_launcher) 
        .setContentTitle("Content Title") 
        .setContentText("Content Text") 
        .setContent(rv) 
        .setPriority( NotificationCompat.PRIORITY_MIN);
    final Notification notification = mBuilder.build();
    // set big content view for newer androids
    if (android.os.Build.VERSION.SDK_INT >= 16) { 
    notification.bigContentView = rv;
    }
    NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 
    mNotificationManager.notify(NOTIFICATION_ID, notification); 
    

    上述创建了三个重要的对象,notification和 RemoteViews以及常量 NOTIFICATION_ID。利用这些去创建一个通知 target。

    private NotificationTarget notificationTarget;
    ...
    notificationTarget = new NotificationTarget( 
        context, 
        rv, 
        R.id.remoteview_notification_icon, 
        notification, 
        NOTIFICATION_ID);
    

    调用 Glide,将 target 作为 .into()的参数。

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

    Transformations(转换)
    在图片被显示之前,transformations(转换) 可以被用于图像的操作处理。图片的任意属性:颜色、尺寸、范围、颜色、像素位置等等。下面的库它为 Glide 转换提供了多种多样的实现:
    glide-transformations

    用 animate() 自定义动画
    创建自己的 XML 动画,比如一个小的缩放动画,图片刚开始小的,然后逐渐增大到原尺寸。

    <?xml version="1.0" encoding="utf-8"?> 
    <set xmlns:android="http://schemas.android.com/apk/res/android" 
    android:fillAfter="true">
    <scale
        android:duration="@android:integer/config_longAnimTime"     
        android:fromXScale="0.1" 
        android:fromYScale="0.1" 
        android:pivotX="50%"  
        android:pivotY="50%" //这两个属性控制着View对象的支点位置,围绕这个支点进行旋转和缩放变换处理
        android:toXScale="1"  //缩放
        android:toYScale="1"/>
    </set> 
    

    这两个动画可以添加到Glid中

    Glide 
        .with( context ) 
        .load( eatFoodyImages[0] ) 
        .animate( android.R.anim.slide_in_left ) //或者R.anim.zoom_in 
        .into( imageView1 );
    

    • 集成网络栈
      集成 OkHttp 作为你给 Glide 的网络库,在build.gradle依赖中添加下面这两行代码:
    dependencies { 
        // your other dependencies 
        // ...
        //Glide 
        compile 'com.github.bumptech.glide:glide:3.6.1' 
        // Glide's OkHttp Integration 
        compile 'com.github.bumptech.glide:okhttp-integration:1.3.1@aar' 
        compile 'com.squareup.okhttp:okhttp:2.5.0'
    }
    

    • 用 Module 自定义 Glide
      为了定制 Glide,你需要去实现一个GlideModule接口的公共类。
    public class SimpleGlideModule implements GlideModule { 
        @Override 
        public void applyOptions(Context context, GlideBuilder builder) { 
            // todo 
        } 
        @Override 
        public void registerComponents(Context context, Glide glide) { 
            // todo 
        }
    }
    

    在 AndroidManifest.xml的 <application>标签内去声明这个刚刚创建的 Glide module。

    <manifest 
        ... 
        <application> 
              <meta-data     
                   android:name="io.futurestud.tutorials.glide.glidemodule.SimpleGlideModule" 
                   android:value="GlideModule" />
         ... 
        </application>
    </manifest> 
    

    android:name属性是包名+类名的形式。
    要看第一个方法applyOptions(Context context, GlideBuilder builder),可以在这个方法里去调 GlideBuilder中可用的方法。

    • setMemoryCache(MemoryCache memoryCache)
    • setBitmapPool(BitmapPool bitmapPool)
    • setDiskCache(DiskCache.Factory diskCacheFactory)
    • setDiskCacheService(ExecutorService service)
    • setResizeService(ExecutorService service)
    • setDecodeFormat(DecodeFormat decodeFormat)
      可以通过这些方法改变磁盘缓存,内存缓存等等。
      示例:增加 Glide 的图片质量
      在 Android 中有两个主要的方法对图片进行解码:ARGB8888 和 RGB565。前者为每个像素使用了 4 个字节,后者仅为每个像素使用了 2 个字节。ARGB8888 的优势是图像质量更高以及能存储一个 alpha 通道。Glide 默认使用低质量的 RGB565。可以使用 Glide module 方法去改变解码规则。
    public class SimpleGlideModule implements GlideModule { 
        @Override 
        public void applyOptions(Context context, GlideBuilder builder) { 
            builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888); 
        } 
        @Override 
        public void registerComponents(Context context, Glide glide) { 
            // nothing to do here 
        }
    }
    

    • 接受自签名证书的 HTTPS
      可能是当你的图片从服务端获取时,是使用HTTPS,且是自签名的(self-signed)。这时 Glide 不会下载或显示图片了,因为自签名的证书被认为是一个安全的问题。

    参考:
    Glide系列教程

    相关文章

      网友评论

          本文标题:Glide使用

          本文链接:https://www.haomeiwen.com/subject/ttkiuttx.html