【问题标题】:Glide ModelLoader that loads either from local or remote从本地或远程加载的 Glide ModelLoader
【发布时间】:2019-03-22 22:16:00
【问题描述】:

我有一个自定义 Glide 模型来计算图像的中心裁剪。相同的模型用于从服务器和本地存储中获取图像。

这是模型界面:

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() {}
    }
}

这适用于具有http/https 方案的图像,但不适用于file 方案 - 用于从本地设备存储加载图像的方案。

我查看了 Glide 的源代码,最接近的 ModelLoader 听起来像是一个选项是UriLoader,但它不支持自定义模型的问题。仅支持Uri

最佳解决方案是使用与 Glide 捆绑在一起的预先存在的 ModelLoader,但除非我错过了它,否则我找不到适合我需要的任何东西。如果真是这样的话,我该如何实现这样的ModelLoader呢?

【问题讨论】:

    标签: android android-image android-glide


    【解决方案1】:

    我在阅读Glide's ModelLoaders tutorial 后想通了。关键是将加载委托给知道如何处理 filehttp/https 方案的 ModelLoader。

    我要做的是直接实现ModelLoader接口,而不是扩展BaseGlideUrlLoader。我们已经知道 Glide 的内置 UriLoader 可以处理 filehttp/https 方案,所以我们委托给它。现在要获取UriLoader 的实例,我们使用传递给我们工厂的build 方法的MultiModelLoaderFactory。默认 Glide 配置为 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() {}
         }
    }
    

    正如我们所见,我们不再扩展 BaseGlideUrlLoader。相反,我们实现ModelLoader 接口,在buildLoadData() 实现中,我们尝试从缓存中获取URI(这类似于BaseGlideUrlLoader 正在做的事情),然后我们在传递给ModelLoader 上调用buildLoadData()构造函数,它恰好是UriLoader 的一个实例,正如我之前提到的,感谢MultiModelLoaderFactory

    这种类型的 ModelLoader 不是 Glide 内置模型加载器的一部分真是令人惊讶。

    【讨论】:

    • 感谢您发布解决方案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    相关资源
    最近更新 更多