安卓Glide加载失败时点击按钮重新加载图片

需求

假设此时已经用load指定一个url: String,又用into指定了一个img: ImageView开始加载,但是网络突然中断,导致图片加载失败。在这种情况下,想要通过点击一个Button重新加载。

Glide.with(context).load(url)
	.placeholder(loadingBitmap)
	.into(img) // 失败后将保持 loadingBitmap

分析1

自然的想法是直接添加一个按钮,在失败时重复执行加载过程:

button.setOnClickListener {
	Glide.with(context).load(url)
		.placeholder(loadingBitmap)
		.into(img) // 失败后将保持 loadingBitmap
}

但是这样做每次点击按钮都会重新执行一遍Glide的构建流程,浪费处理资源。

分析2

在Glide处理时增加一个监听器,只有onLoadFailed亦即加载失败时,才将按钮设为可点击,并且撤销之前的监听器。同时,为按钮增加一个监控变量,确保其只被点击了一次,避免重复加载(退化为分析1)。
代码比较复杂,这里略去不写。

分析3

实际上Glide自身存在控制资源重新加载的方式,即Target。因此,不需要任何重初始化,只要调用Target的相关函数刷新加载请求即可。

解决方案

分析3编写为一个简单的类如下。

class RequestReloadingButtonListener<T>(private val button: Button) : RequestListener<T> {
	var mTarget: Target<T>? = null
	init {
		button.apply { post {
			setOnClickListener { mTarget?.request?.apply {
				clear()		// 取消上次请求
				begin()		// 异步开始新请求
			} }
		} }
	}
	override fun onLoadFailed(
		e: GlideException?,
		model: Any?,
		target: Target<T>,
		isFirstResource: Boolean
	): Boolean {
		button.visibility = View.VISIBLE	// 显示重加载按钮
		mTarget = target					// 记录请求目标
		return false
	}
	override fun onResourceReady(
		resource: T & Any,
		model: Any,
		target: Target<T>?,
		dataSource: DataSource,
		isFirstResource: Boolean
	): Boolean {
		button.visibility = View.GONE		// 隐藏重加载按钮
		return false
	}
}

这样一来,通过如下代码即可实现加载失败时显示重加载按钮,用户点击后重新加载:

Glide.with(context).load(url)
	.placeholder(loadingBitmap)
	.addListener(RequestReloadingButtonListener(button))
	.into(img)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里是一个完整的示例代码,它允许用户在Android应用中点按钮选择图片,并在页面中显示: 1. 创建一个新的Android项目,并在activity_main.xml布局文件中添以下代码: ```xml <?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="match_parent" android:orientation="vertical"> <Button android:id="@+id/button_choose_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Choose Image" /> <ImageView android:id="@+id/image_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="centerInside" /> </LinearLayout> ``` 这个布局文件包含一个按钮和一个ImageView组件,当用户点按钮时,可以从设备的相册中选择图片,并将其显示在ImageView中。 2. 在MainActivity.java文件中添以下代码: ```java import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.widget.Button; import android.widget.ImageView; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import com.bumptech.glide.Glide; public class MainActivity extends AppCompatActivity { private static final int PICK_IMAGE_REQUEST = 1; private Button mButtonChooseImage; private ImageView mImageView; private Uri mImageUri; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButtonChooseImage = findViewById(R.id.button_choose_image); mImageView = findViewById(R.id.image_view); mButtonChooseImage.setOnClickListener(v -> openFileChooser()); } private void openFileChooser() { Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); intent.setType("image/*"); startActivityForResult(intent, PICK_IMAGE_REQUEST); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) { mImageUri = data.getData(); Glide.with(this).load(mImageUri).into(mImageView); } } } ``` 这个代码中,我们首先定义了一个常量PICK_IMAGE_REQUEST,用于标识选择图片的请求。然后在onCreate方法中,我们获取了按钮和ImageView的实例,并为按钮了一个点事件监听器。当按钮被点时,我们调用openFileChooser方法打开图库,并在onActivityResult方法中处理选择图片的结果。 在openFileChooser方法中,我们创建了一个Intent对象,并设置其类型为image/*,这样它只会显示图片文件。然后我们使用startActivityForResult方法启动该Intent。 最后,在onActivityResult方法中,我们检查请求码和结果码是否匹配,并检查返回的Intent是否包含数据。如果是,我们将URI保存在mImageUri变量中,并使用Glide库将其到ImageView中。 需要注意的是,你需要在你的AndroidManifest.xml文件中添以下权限: ```xml <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> ``` 这个权限将允许你的应用程序读取设备上的图库文件。 希望这个示例代码能够帮助到你。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值