Glide as a picture loading library just began to become popular in recent years, the function is very powerful, I believe that a lot of people began to use Glide in the project, the use of the online Glide tutorial is also very much, recently in the project to achieve the picture of the progress bar loading, on the Internet did not see a ready-made, I want to study.
use
Glide.with(MainActivity.this).using(new ProgressModelLoader(
new ProgressHandler(MainActivity.this, progressImageView))).
load("http://image2.sina.com.cn/dy/o/2004-11-10/1100077821_2laygS.jpg")
.diskCacheStrategy(DiskCacheStrategy.NONE).into(progressImageView.getImageView());Copy the code
Train of thought
Glide picture download bottom with OkHttp, it has been implemented, all to achieve progress bar loading, you must know the progress of picture download, you have to write down the picture to achieve, but Glide support does not support it? I looked it up online and found a way to do it
public <T> ImageModelRequest<T> using(final StreamModelLoader<T> modelLoader) {
return new ImageModelRequest<T>(modelLoader);
}Copy the code
This method specifies the image request loader. We create a ProgressModelLoader class that implements the StreamModelLoader interface
public class ProgressModelLoader implements StreamModelLoader<String> {
private Handler handler;
public ProgressModelLoader(Handler handler) {
this.handler = handler;
}
@Override
public DataFetcher<InputStream> getResourceFetcher(String model, int width, int height) {
return new ProgressDataFetcher(model, handler); }}Copy the code
Override getResourceFetcher, which returns a DataFetcher class that is a data extraction class and is an interface, override its loadData method to download the image, Let’s look at my ProgressDataFetcher overwriting the loadData method
@Override
public InputStream loadData(Priority priority) throws Exception {
Request request = new Request.Builder().url(url).build();
OkHttpClient client = new OkHttpClient(a); client.interceptors().add(new ProgressInterceptor(getProgressListener()));
try {
progressCall = client.newCall(request);
Response response = progressCall.execute();
if (isCancelled) {
return null;
}
if(! response.isSuccessful())throw new IOException("Unexpected code " + response);
stream = response.body().byteStream();
} catch (IOException e) {
e.printStackTrace();
return null;
}
return stream;
}Copy the code
Use okHTTP to download images and add an interceptor
public class ProgressInterceptor implements Interceptor {
private ProgressListener progressListener;
public ProgressInterceptor(ProgressListener progressListener) {
this.progressListener = progressListener;
}
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder().body(newProgressResponseBody(originalResponse.body(), progressListener)).build(); }}Copy the code
Rewrite the Intercept method and create a ProgressResponseBody to get the progress of the image download. Let’s see how to read the stream
private Source source(Source source) {
return new ForwardingSource(source) {
long totalBytesRead = 0;
@Override
public long read(Buffer sink, long byteCount) throws IOException {
long bytesRead = super.read(sink, byteCount); totalBytesRead += bytesRead ! = -1 ? bytesRead : 0;
if(progressListener ! =null)
progressListener.progress(totalBytesRead, responseBody.contentLength(), bytesRead == -1);
returnbytesRead; }}; }Copy the code
To read bytesRead and responseBody contentLength progressListener () to the callback method. The calculated on the basis of the progress schedule.
This is the end of the general implementation logic. To see the complete code, go to github.com/chenpengfei…
Welcome Star, Follow, thank you.