Glide高级介绍

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 source

Matrix 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/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值