使用 Glide 加载图像时的进度条

我是否可以在占位符中加载旋转动画,直到使用 Glide 加载图像?

I am trying to do that using .placeholder(R.Drawable.spinner) no animation is coming up?

如果有人能帮我就太好了?

谢谢!

117087 次浏览

编辑: 使用 CircularProgressDrawable,现在超级简单了

建造,分级

implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"

MyGlideModule.kt

@GlideModule
class MyGlideModule : AppGlideModule()

MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)


val circularProgressDrawable = CircularProgressDrawable(this)
circularProgressDrawable.strokeWidth = 5f
circularProgressDrawable.centerRadius = 30f
circularProgressDrawable.start()


GlideApp.with(applicationContext)
.load("https://raw.githubusercontent.com/bumptech/glide/master/static/glide_logo.png")
.placeholder(circularProgressDrawable)
.into(a_main_image)
}

这些是其他的 滑翔片段


旧的回答是: 您也可以创建一个普通的 ProgressBar,然后将其隐藏在 Glide 的 onResourceReady()中。

资源加载完成后将调用的方法。


Example:

MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


final ImageView imageView = (ImageView) findViewById(R.id.img_glide);
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress);


Glide.with(this)
.load("https://raw.githubusercontent.com/bumptech/glide/master/static/glide_logo.png")
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
progressBar.setVisibility(View.GONE);
return false;
}


@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
progressBar.setVisibility(View.GONE);
return false;
}
})
.into(imageView);
}

Activity _ main.xml (布局) :

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">


<ProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="100dp"
android:visibility="visible" />


<ImageView
android:id="@+id/img_glide"
android:layout_width="match_parent"
android:layout_height="100dp" />


</RelativeLayout>

结果:

enter image description here

You can set progress value whatever you want with my GlideImageLoader.

I hope it will solve your question.

APP DEMO

我在 GlideImageLoader.java 和 ProgressAppGlideModule.java 中封装了图像加载器

如何实施以下三个步骤:

1. 构建. 分级

//Glide
implementation 'com.github.bumptech.glide:glide:4.4.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.4.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.4.0'

2. 将 GlideImageLoader.Java 和 ProgressAppGlideModule. Java 克隆到你的项目中

3. 随时随地使用

RequestOptions options = new RequestOptions()
.centerCrop()
.placeholder(R.drawable.placeholder)
.error(R.drawable.ic_pic_error)
.priority(Priority.HIGH);


new GlideImageLoader(YOUR.imageView,
YOUR.progressBar).load(url,options);

完整的克隆 Java 代码:

GlideImageLoader.java

public class GlideImageLoader {


private ImageView mImageView;
private ProgressBar mProgressBar;


public GlideImageLoader(ImageView imageView, ProgressBar progressBar) {
mImageView = imageView;
mProgressBar = progressBar;
}


public void load(final String url, RequestOptions options) {
if (url == null || options == null) return;


onConnecting();


//set Listener & start
ProgressAppGlideModule.expect(url, new ProgressAppGlideModule.UIonProgressListener() {
@Override
public void onProgress(long bytesRead, long expectedLength) {
if (mProgressBar != null) {
mProgressBar.setProgress((int) (100 * bytesRead / expectedLength));
}
}


@Override
public float getGranualityPercentage() {
return 1.0f;
}
});
//Get Image
Glide.with(mImageView.getContext())
.load(url)
.transition(withCrossFade())
.apply(options.skipMemoryCache(true))
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
ProgressAppGlideModule.forget(url);
onFinished();
return false;
}


@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
ProgressAppGlideModule.forget(url);
onFinished();
return false;
}
})
.into(mImageView);
}




private void onConnecting() {
if (mProgressBar != null) mProgressBar.setVisibility(View.VISIBLE);
}


private void onFinished() {
if (mProgressBar != null && mImageView != null) {
mProgressBar.setVisibility(View.GONE);
mImageView.setVisibility(View.VISIBLE);
}
}
}

Java

@GlideModule
public class ProgressAppGlideModule extends AppGlideModule {


@Override
public void registerComponents(Context context, Glide glide, Registry registry) {
super.registerComponents(context, glide, registry);
OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
ResponseProgressListener listener = new DispatchingProgressListener();
return response.newBuilder()
.body(new OkHttpProgressResponseBody(request.url(), response.body(), listener))
.build();
}
})
.build();
registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(client));
}


public static void forget(String url) {
ProgressAppGlideModule.DispatchingProgressListener.forget(url);
}
public static void expect(String url, ProgressAppGlideModule.UIonProgressListener listener) {
ProgressAppGlideModule.DispatchingProgressListener.expect(url, listener);
}


private interface ResponseProgressListener {
void update(HttpUrl url, long bytesRead, long contentLength);
}


public interface UIonProgressListener {
void onProgress(long bytesRead, long expectedLength);
/**
* Control how often the listener needs an update. 0% and 100% will always be dispatched.
* @return in percentage (0.2 = call {@link #onProgress} around every 0.2 percent of progress)
*/
float getGranualityPercentage();
}


private static class DispatchingProgressListener implements ProgressAppGlideModule.ResponseProgressListener {
private static final Map<String, UIonProgressListener> LISTENERS = new HashMap<>();
private static final Map<String, Long> PROGRESSES = new HashMap<>();


private final Handler handler;


DispatchingProgressListener() {
this.handler = new Handler(Looper.getMainLooper());
}


static void forget(String url) {
LISTENERS.remove(url);
PROGRESSES.remove(url);
}


static void expect(String url, UIonProgressListener listener) {
LISTENERS.put(url, listener);
}


@Override
public void update(HttpUrl url, final long bytesRead, final long contentLength) {
//System.out.printf("%s: %d/%d = %.2f%%%n", url, bytesRead, contentLength, (100f * bytesRead) / contentLength);
String key = url.toString();
final UIonProgressListener listener = LISTENERS.get(key);
if (listener == null) {
return;
}
if (contentLength <= bytesRead) {
forget(key);
}
if (needsDispatch(key, bytesRead, contentLength, listener.getGranualityPercentage())) {
handler.post(new Runnable() {
@Override
public void run() {
listener.onProgress(bytesRead, contentLength);
}
});
}
}


private boolean needsDispatch(String key, long current, long total, float granularity) {
if (granularity == 0 || current == 0 || total == current) {
return true;
}
float percent = 100f * current / total;
long currentProgress = (long) (percent / granularity);
Long lastProgress = PROGRESSES.get(key);
if (lastProgress == null || currentProgress != lastProgress) {
PROGRESSES.put(key, currentProgress);
return true;
} else {
return false;
}
}
}


private static class OkHttpProgressResponseBody extends ResponseBody {
private final HttpUrl url;
private final ResponseBody responseBody;
private final ResponseProgressListener progressListener;
private BufferedSource bufferedSource;


OkHttpProgressResponseBody(HttpUrl url, ResponseBody responseBody,
ResponseProgressListener progressListener) {
this.url = url;
this.responseBody = responseBody;
this.progressListener = progressListener;
}


@Override
public MediaType contentType() {
return responseBody.contentType();
}


@Override
public long contentLength() {
return responseBody.contentLength();
}


@Override
public BufferedSource source() {
if (bufferedSource == null) {
bufferedSource = Okio.buffer(source(responseBody.source()));
}
return bufferedSource;
}


private Source source(Source source) {
return new ForwardingSource(source) {
long totalBytesRead = 0L;


@Override
public long read(Buffer sink, long byteCount) throws IOException {
long bytesRead = super.read(sink, byteCount);
long fullLength = responseBody.contentLength();
if (bytesRead == -1) { // this source is exhausted
totalBytesRead = fullLength;
} else {
totalBytesRead += bytesRead;
}
progressListener.update(url, totalBytesRead, fullLength);
return bytesRead;
}
};
}
}
}

我在 Kotlin 编写一个应用程序,遇到了同样的问题,但不幸的是,被接受的答案是 Java。所以我在 Kotlin 重写了一遍。

Glide.with(context)
.load("<Insert Your URL>")
.listener(object : RequestListener<Drawable> {
override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
progressBar.visibility = View.GONE
return false
}


override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
progressBar.visibility = View.GONE
return false
}
})
.into(holder.imageView)

尝试 使用 < a href = “ http://bumptech.github.io/glide/doc/igrating.html # RequestOptions”rel = “ nofollow noReferrer”> RequestOptions

RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(R.drawable.ic_placeholder);
requestOptions.error(R.drawable.ic_error);




Glide.with(MainActivity.this)
.load(url)
.apply(requestOptions)
.into(imageview);

这是使用 滑行实现加载图像的一种方法。

另一个技巧: 把你的 ImageView放在一个 RelativeLayout背后有一个 ProgressBar。然后通过 Glide 或 Picasso 加载图像。它不需要深入挖掘就能为你完成工作。您不再需要隐藏或显示进度条。它将被图像完全重叠。

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/_180sdp">
<ProgressBar
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/iv_image"
android:layout_width="match_parent"
android:layout_height="@dimen/_180sdp"
android:scaleType="centerCrop"/>
</RelativeLayout>

是的,我们可以使用 GlideRequestOptions 在 ImageView 上显示加载程序。
1)在应用程序级别的分级文件中使用下面的编译行。 < br >

实现‘ com.github.umptech.glide: glide: 4.8.0’ 注释处理器‘ com.github.bumptech.glide: 编译器: 4.8.0’

2)Add progress_animation.xml file in drawable

<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/loader_test"
android:pivotX="50%"
android:pivotY="50%"/>

3)添加以下 loader _ test.png 图像在绘制
enter image description here

4)按以下方式创建 RequestOption

public  RequestOptions options = new RequestOptions()
.centerCrop()
.placeholder(R.drawable.progress_animation)
.error(R.drawable.user_image)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.priority(Priority.HIGH)
.dontAnimate()
.dontTransform();

5)最后使用这个加载图像如下所示

Glide.with(this).load(//*Your image url*//).apply(options).into(image_view);

Here is my complete solution with a circle loading progress. I think it is better to use requestOptionsattributes to achieve this.

CircularProgressDrawable circularProgressDrawable = new CircularProgressDrawable(context);
circularProgressDrawable.setStrokeWidth(5f);
circularProgressDrawable.setCenterRadius(30f);
circularProgressDrawable.start();


RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(circularProgressDrawable);
requestOptions.error(R.drawable.ic_image_not_found);
requestOptions.skipMemoryCache(true);
requestOptions.fitCenter();




glide.load(imagePath) //passing your url to load image.
.load(imagePath)
.apply(requestOptions) // here you have all options you need
.transition(DrawableTransitionOptions.withCrossFade()) // when image (url) will be loaded by glide then this face in animation help to replace url image in the place of placeHolder (default) image.
.listener(requestListener)
.into(view); //pass imageView reference to appear the image.

And you got it.

步骤 -1创建可绘制的 Progress _ anime.xml

<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/loader_test"
android:pivotX="50%"
android:pivotY="50%"/>

步骤2下载 loader _ test 并保存为可绘制的。

第3步为动画加载

步骤4在出错的情况下,用户可以设置错误图像中的错误

 Glide.with(this).load(url).apply(
RequestOptions().placeholder(R.drawable.progress_animation).error((R.drawable.ic_account)).centerCrop()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.priority(Priority.HIGH)
.transform(CenterCrop(), RoundedCorners(1000)))
.into(image_view)