Glide高级介绍

来源:互联网 发布:围棋入门那个软件 编辑:程序博客网 时间:2024/05/21 21:45

Transformations

需要实现Transformation接口,推荐使用抽象类BitmapTransformation.

public class BlurTransformation extends BitmapTransformation {    public BlurTransformation(Context context) {        super( context );    }    @Override    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {        return null; // todo    }    @Override    public String getId() {        return null; // todo    }}

应用转换

Glide      .with( context )    .load( eatFoodyImages[0] )    .transform( new BlurTransformation( context ),new xxxxx....,...)    //.bitmapTransform( new BlurTransformation( context ) ) // this would work too!    .into( imageView1 );    //当使用了transform()之后不能使用.centerCrop()或.fitCenter()。

Glide转换设置

https://github.com/wasabeef/glide-transformations 提供了Glide转换的多种实现。
使用方法:
build.gradle:

dependencies {      compile 'jp.wasabeef:glide-transformations:1.2.1'}

GPU转换:

repositories {      jcenter()    mavenCentral()}dependencies {      compile 'jp.wasabeef:glide-transformations:1.2.1'    compile 'jp.co.cyberagent.android.gpuimage:gpuimage-library:1.3.0'}

如果你想使用 BlurTransformation,你需要多一个步骤。如果你还没做的话,那就添加下面这些代码到你的 build.gradle中。

android {      ...    defaultConfig {        ...        renderscriptTargetApi 23        renderscriptSupportModeEnabled true    }}

Glide转换使用

Glide      .with( context )    .load( eatFoodyImages[2] )    .bitmapTransform( new jp.wasabeef.glide.transformations.BlurTransformation( context, 25, 2 ) )    .into( imageView3 );

Glide动画显示

加载资源中的动画

<?xml version="1.0" encoding="utf-8"?>  <set xmlns:android="http://schemas.android.com/apk/res/android">      <translate android:fromXDelta="-50%p" android:toXDelta="0"            android:duration="@android:integer/config_mediumAnimTime"/>    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"            android:duration="@android:integer/config_mediumAnimTime" /></set> 
Glide      .with( context )    .load( eatFoodyImages[0] )    .animate( android.R.anim.slide_in_left ) // or R.anim.zoom_in    .into( imageView1 );

自定义类实现动画

ViewPropertyAnimation.Animator animationObject = new ViewPropertyAnimation.Animator() {      @Override    public void animate(View view) {        // if it's a custom view class, cast it here        // then find subviews and do the animations        // here, we just use the entire view for the fade animation        view.setAlpha( 0f );        ObjectAnimator fadeAnim = ObjectAnimator.ofFloat( view, "alpha", 0f, 1f );        fadeAnim.setDuration( 2500 );        fadeAnim.start();    }};
Glide      .with( context )    .load( eatFoodyImages[1] )    .animate( animationObject )    .into( imageView2 );

集成网络栈

OkHttp:

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'}//Gradle 会自动合并必要的 GlideModule 到你的 Android.Manifest。Glide 会认可在 manifest 中的存在,然后使用 OkHttp 做到所有的网络连接。

Volley:

dependencies {      // Glide    compile 'com.github.bumptech.glide:glide:3.6.1'    // Glide's Volley Integration     compile 'com.github.bumptech.glide:volley-integration:1.3.1@aar'    compile 'com.mcxiaoke.volley:library:1.0.8'}

如果你把这两个库都在你的 build.gradle 中声明了,那这两个库都会被添加。因为 Glide 没有任何特殊的加载顺序,你将会有一个不稳定的状态,它并不明确使用哪个网络库,所以确保你只添加了一个集成库。

Glide Modules

Glide Module是一个抽象方法,会全局改变Glide行为。

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中进行声明:

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

GlideBuilder中可用的方法如下:

.setMemoryCache(MemoryCache memoryCache).setBitmapPool(BitmapPool bitmapPool).setDiskCache(DiskCache.Factory diskCacheFactory).setDiskCacheService(ExecutorService service).setResizeService(ExecutorService service).setDecodeFormat(DecodeFormat decodeFormat)

Glide默认使用的图片解码是RGB565,如果想增加图片质量,可以这样:

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    }}

Glide内部使用HTTPURLConnection去下载图片,缺点是当图片从服务器获取时,如果使用了HTTPS,同时是自签名的,Glide就不会下载或显示图片了。

UnsafeOkHttpClient

创建 OkHttpClient 禁用掉所有的 SSL 证书检查

public class UnsafeOkHttpClient {      public static OkHttpClient getUnsafeOkHttpClient() {        try {            // Create a trust manager that does not validate certificate chains            final TrustManager[] trustAllCerts = new TrustManager[]{                    new X509TrustManager() {                        @Override                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {                        }                        @Override                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {                        }                        @Override                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {                            return null;                        }                    }            };            // Install the all-trusting trust manager            final SSLContext sslContext = SSLContext.getInstance("SSL");            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());            // Create an ssl socket factory with our all-trusting manager            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();            OkHttpClient okHttpClient = new OkHttpClient();            okHttpClient.setSslSocketFactory(sslSocketFactory);            okHttpClient.setProtocols(Arrays.asList(Protocol.HTTP_1_1));            okHttpClient.setHostnameVerifier(new HostnameVerifier() {                @Override                public boolean verify(String hostname, SSLSession session) {                    return true;                }            });            return okHttpClient;        } catch (Exception e) {            throw new RuntimeException(e);        }    }}

OkHttp 整合库为 Glide 做了几乎相同的事情,所以我们可以跟着他们走。首先,我们需要在 GlideModule 中声明我们的定制。正如你所期待的,我们要在 registerComponents() 方法中去做适配。我们可以调用 .register() 方法去改变 Glide 的基本部件。Glide 使用一个 GlideLoader 去链接数据模型到一个具体的数据类型。在我们的实例中,我们要去创建一个 ModeLoader,连接传入的 URL,通过 GlideUrl 类来代表一个 InputStream。Glide 要能创建一个我们的新的 ModeLoader,所以我们要在 .register() 方法中传递一个工厂。

public class UnsafeOkHttpGlideModule implements GlideModule {          @Override        public void applyOptions(Context context, GlideBuilder builder) {        }        @Override        public void registerComponents(Context context, Glide glide) {            glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());        }    }
ublic class OkHttpUrlLoader implements ModelLoader<GlideUrl, InputStream> {    /**     * The default factory for {@link OkHttpUrlLoader}s.     */    public static class Factory implements ModelLoaderFactory<GlideUrl, InputStream> {        private static volatile OkHttpClient internalClient;        private OkHttpClient client;        private static OkHttpClient getInternalClient() {            if (internalClient == null) {                synchronized (Factory.class) {                    if (internalClient == null) {                        internalClient = UnsafeOkHttpClient.getUnsafeOkHttpClient();                    }                }            }            return internalClient;        }        /**         * Constructor for a new Factory that runs requests using a static singleton client.         */        public Factory() {            this(getInternalClient());        }        /**         * Constructor for a new Factory that runs requests using given client.         */        public Factory(OkHttpClient client) {            this.client = client;        }        @Override        public ModelLoader<GlideUrl, InputStream> build(Context context, GenericLoaderFactory factories) {            return new OkHttpUrlLoader(client);        }        @Override        public void teardown() {            // Do nothing, this instance doesn't own the client.        }    }    private final OkHttpClient client;    public OkHttpUrlLoader(OkHttpClient client) {        this.client = client;    }    @Override    public DataFetcher<InputStream> getResourceFetcher(GlideUrl model, int width, int height) {        return new OkHttpStreamFetcher(client, model);    }}

不幸的是,我们仍然需要用我们的不安全的 OKHttpClient 去连接 URL 激活输入流。因此,我们需要另外一个类去从一个 URL 中拉取返回的输入流:

public class OkHttpStreamFetcher implements DataFetcher<InputStream> {      private final OkHttpClient client;    private final GlideUrl url;    private InputStream stream;    private ResponseBody responseBody;    public OkHttpStreamFetcher(OkHttpClient client, GlideUrl url) {        this.client = client;        this.url = url;    }    @Override    public InputStream loadData(Priority priority) throws Exception {        Request.Builder requestBuilder = new Request.Builder()                .url(url.toStringUrl());        for (Map.Entry<String, String> headerEntry : url.getHeaders().entrySet()) {            String key = headerEntry.getKey();            requestBuilder.addHeader(key, headerEntry.getValue());        }        Request request = requestBuilder.build();        Response response = client.newCall(request).execute();        responseBody = response.body();        if (!response.isSuccessful()) {            throw new IOException("Request failed with code: " + response.code());        }        long contentLength = responseBody.contentLength();        stream = ContentLengthInputStream.obtain(responseBody.byteStream(), contentLength);        return stream;    }    @Override    public void cleanup() {        if (stream != null) {            try {                stream.close();            } catch (IOException e) {                // Ignored            }        }        if (responseBody != null) {            try {                responseBody.close();            } catch (IOException e) {                // Ignored.            }        }    }    @Override    public String getId() {        return url.getCacheKey();    }    @Override    public void cancel() {        // TODO: call cancel on the client when this method is called on a background thread. See #257    }}

如何使用Glide旋转图片

android.graphics.Matrix 提供了办法:

Bitmap toTransform = ... // your bitmap sourceMatrix matrix = new Matrix();  matrix.postRotate(rotateRotationAngle);Bitmap.createBitmap(toTransform, 0, 0, toTransform.getWidth(), toTransform.getHeight(), matrix, true); 

在自定义转换中进行图片翻转:

public class RotateTransformation extends BitmapTransformation {    private float rotateRotationAngle = 0f;    public RotateTransformation(Context context, float rotateRotationAngle) {        super( context );        this.rotateRotationAngle = rotateRotationAngle;    }    @Override    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {        Matrix matrix = new Matrix();        matrix.postRotate(rotateRotationAngle);        return Bitmap.createBitmap(toTransform, 0, 0, toTransform.getWidth(), toTransform.getHeight(), matrix, true);    }    @Override    public String getId() {        return "rotate" + rotateRotationAngle;    }}
Glide        .with( context )        .load( eatFoodyImages[0] )        .transform( new RotateTransformation( context, 90f ))        .into( imageView3 );

ThanksTo:https://mrfu.me/2016/02/27/Glide_Getting_Started/

0 0