Android 从本地或远程加载的Glide ModelLoader
我有一个自定义的滑动模型来计算图像的中心裁剪。相同的模型用于从服务器和本地存储获取图像 以下是模型界面:Android 从本地或远程加载的Glide ModelLoader,android,android-image,android-glide,Android,Android Image,Android Glide,我有一个自定义的滑动模型来计算图像的中心裁剪。相同的模型用于从服务器和本地存储获取图像 以下是模型界面: interface CenterCropImageInformation { fun getCenterCropUri(context: Context, @Px width: Int, @Px height: Int): Uri } 下面是它的ModelLoader,它从BaseGlideUrlLoader扩展而来: class CenterCropImageInformatio
interface CenterCropImageInformation {
fun getCenterCropUri(context: Context, @Px width: Int, @Px height: Int): Uri
}
下面是它的ModelLoader,它从BaseGlideUrlLoader
扩展而来:
class CenterCropImageInformationLoader private constructor(
context: Context,
concreteLoader: ModelLoader<GlideUrl, InputStream>,
modelCache: ModelCache<CenterCropImageInformation, GlideUrl>?
) : BaseGlideUrlLoader<CenterCropImageInformation>(concreteLoader, modelCache) {
private val applicationContext: Context = context.applicationContext
override fun getUrl(
model: CenterCropImageInformation, width: Int,
height: Int, options: Options
): String {
return model.getCenterCropUri(applicationContext, width, height).toString()
}
override fun handles(centerCropImageInformation: CenterCropImageInformation): Boolean {
return true
}
/**
* The default factory for [CenterCropImageInformation]s.
*/
class Factory(
private val applicationContext: Context,
private val modelCache: ModelCache<CenterCropImageInformation, GlideUrl>?
) : ModelLoaderFactory<CenterCropImageInformation, InputStream> {
override fun build(
multiFactory: MultiModelLoaderFactory
): ModelLoader<CenterCropImageInformation, InputStream> {
val modelLoader = multiFactory.build(GlideUrl::class.java, InputStream::class.java)
return CenterCropImageInformationLoader(applicationContext, modelLoader, modelCache)
}
override fun teardown() {}
}
}
class CenterCropImageInformationLoader私有构造函数(
上下文:上下文,
混凝土加载器:模型加载器,
modelCache:modelCache?
):BaseGlideUrlLoader(concreteLoader、modelCache){
私有val applicationContext:Context=Context.applicationContext
覆盖有趣的getUrl(
型号:CenterCropImageInformation,宽度:Int,
高度:Int,选项:选项
):字符串{
return model.getCenterCropUri(applicationContext,width,height).toString()
}
覆盖有趣的句柄(centerCropImageInformation:centerCropImageInformation):布尔值{
返回真值
}
/**
*[CenterCropImageInformation]的默认工厂。
*/
阶级工厂(
私有val应用上下文:上下文,
私有val模型缓存:模型缓存?
):ModelLoaderFactory{
覆盖有趣的构建(
多因素:多因素工厂
):ModelLoader{
val modelLoader=multiFactory.build(GlideUrl::class.java,InputStream::class.java)
return CenterCropImageInformationLoader(applicationContext、modelLoader、modelCache)
}
覆盖有趣的拆卸(){}
}
}
这适用于具有http/https
方案的图像,但不适用于用于从本地设备存储加载图像的file
方案
我查看了Glide的源代码,最接近的ModelLoader听起来像是一个选项,它是UriLoader
,但问题是它不支持自定义模型。它只支持Uri
最佳的解决方案是使用一个与Glide捆绑在一起的预先存在的ModelLoader,但是除非我错过了它,否则我找不到任何适合我需要的。如果真是这样的话,我该如何实现这样的ModelLoader呢?我读了之后就明白了。关键是将加载委托给知道如何处理
文件
和http/https
方案的ModelLoader
我要做的是直接实现ModelLoader
接口,而不是扩展BaseGlideUrlLoader
。我们已经知道Glide的内置UriLoader
可以处理文件
和http/https
方案,所以我们将其委托给它。现在,为了获得UriLoader
的实例,我们使用传递给我们工厂的build
方法的multivelloaderfactory
。默认滑动配置为Uri
+InputStream
对注册UriLoader
class CenterCropImageInformationLoader(
private val modelLoader: ModelLoader<Uri, InputStream>,
private val modelCache: ModelCache< CenterCropImageInformation, Uri>
) : ModelLoader<CenterCropImageInformation, InputStream> {
override fun buildLoadData(
model: CenterCropImageInformation,
width: Int,
height: Int,
options: Options
): ModelLoader.LoadData<InputStream>? {
val uri: Uri = modelCache.get(model, width, height) ?: model.getUri(model, width, height)
modelCache.put(model, width, height, uri)
return modelLoader.buildLoadData(uri, width, height, options)
}
override fun handles(model: CenterCropImageInformation): Boolean = true
class Factory(
private val applicationContext: Context,
private val modelCache: ModelCache<CenterCropImageInformation, Uri>
) : ModelLoaderFactory<CenterCropImageInformation, InputStream> {
override fun build(
multiFactory: MultiModelLoaderFactory
): ModelLoader<CenterCropImageInformation, InputStream> {
val modelLoader = multiFactory.build(Uri::class.java, InputStream::class.java)
return CenterCropImageInformationLoader(applicationContext, modelLoader, modelCache)
}
override fun teardown() {}
}
}
类中心CropimageInformationLoader(
私有val模型加载器:模型加载器,
私有val modelCache:modelCache
):ModelLoader{
覆盖buildLoadData(
型号:CenterCropImageInformation,
宽度:Int,
高度:Int,
选项:选项
):ModelLoader.LoadData{
val-uri:uri=modelCache.get(model,width,height)?:model.getUri(model,width,height)
放置(模型、宽度、高度、uri)
返回modelLoader.buildLoadData(uri、宽度、高度、选项)
}
覆盖有趣的句柄(型号:CenterCropImageInformation):布尔值=真
阶级工厂(
私有val应用上下文:上下文,
私有val modelCache:modelCache
):ModelLoaderFactory{
覆盖有趣的构建(
多因素:多因素工厂
):ModelLoader{
val modelLoader=multiFactory.build(Uri::class.java,InputStream::class.java)
return CenterCropImageInformationLoader(applicationContext、modelLoader、modelCache)
}
覆盖有趣的拆卸(){}
}
}
正如我们所看到的,我们不再扩展baseglideurloader
。相反,我们实现了ModelLoader
接口,在buildLoadData()
实现中,我们尝试从缓存中获取URI(这类似于BaseGlideUrlLoader
正在做的事情),然后在传递给构造函数的ModelLoader
上调用buildLoadData(),这恰好是我前面提到的UriLoader
的一个实例,多亏了multivelloaderfactory
这种类型的ModelLoader不是Glide内置model Loader的一部分,这真是令人惊讶。感谢您发布解决方案!