android - 无法在 Android 上加载 svg 资源

标签 android kotlin android-glide

在项目中使用implementation 'com.github.bumptech.glide:glide:4.8.0'

从服务器链接获取(.svg)

如何下​​载给定 url 的 .svg 图标并使用 glide 在 ImageView 中显示它?

现在我像这样使用它:

Glide.with(bankLogoView.context)
            .`as`(PictureDrawable::class.java)
            .load(data.logoUrl)
            .listener(SvgSoftwareLayerSetter())
            .apply(options)
            .into(bankLogoView)

哪里有:

private val options = RequestOptions().centerCrop()
        .diskCacheStrategy(DiskCacheStrategy.ALL).placeholder(R.drawable.ic_logo_splash)

还添加了下一个类SvgDecoder:

class SvgDecoder : ResourceDecoder<InputStream, SVG> {

override fun handles(source: InputStream, options: Options): Boolean {
    // TODO: Can we tell?
    return true
}

@Throws(IOException::class)
override fun decode(source: InputStream, width: Int, height: Int,
                    options: Options): Resource<SVG>? {
    try {
        val svg = SVG.getFromInputStream(source)
        return SimpleResource(svg)
    } catch (ex: SVGParseException) {
        throw IOException("Cannot load SVG from stream", ex)
    }
}
}

SvgDrawableTranscoder:

class SvgDrawableTranscoder : ResourceTranscoder<SVG, PictureDrawable> {

override fun transcode(toTranscode: Resource<SVG>,
                       options: Options): Resource<PictureDrawable>? {
    val svg = toTranscode.get()
    val picture = svg.renderToPicture()
    val drawable = PictureDrawable(picture)
    return SimpleResource(drawable)
}
}

SvgModule:

@GlideModule
class SvgModule : AppGlideModule() {
override fun registerComponents(context: Context, glide: Glide,
                                registry: Registry) {
    registry.register(SVG::class.java, PictureDrawable::class.java, SvgDrawableTranscoder())
            .append(InputStream::class.java, SVG::class.java, SvgDecoder())
}

// Disable manifest parsing to avoid adding similar modules twice.
override fun isManifestParsingEnabled(): Boolean {
    return false
}
}

SvgSoftwareLayerSetter:

class SvgSoftwareLayerSetter : RequestListener<PictureDrawable> {

override fun onLoadFailed(e: GlideException?, model: Any, target: Target<PictureDrawable>,
                          isFirstResource: Boolean): Boolean {
    val view = (target as ImageViewTarget<*>).view
    view.setLayerType(ImageView.LAYER_TYPE_NONE, null)
    return false
}

override fun onResourceReady(resource: PictureDrawable, model: Any,
                             target: Target<PictureDrawable>, dataSource: DataSource, isFirstResource: Boolean): Boolean {
    val view = (target as ImageViewTarget<*>).view
    view.setLayerType(ImageView.LAYER_TYPE_SOFTWARE, null)
    return false
}
}

但我也只显示选项。 data.logoUrl不为空但不显示

更新:

W/Glide: Load failed for https://mandarine.com/logos/providers/xf/fake_demobank_xf.svg with size [65x66] class com.bumptech.glide.load.engine.GlideException: Failed to load resource

当我 .load("url") 时尝试硬编码来自 google 的一些 url,例如:

https://upload.wikimedia.org/wikipedia/sco/7/71/Pringles.svg

但也没有显示图像。

我尝试做的第二种方式: 实现这个 library

implementation 'com.caverock:androidsvg-aar:1.3'

然后修改我的布局:

<com.caverock.androidsvg.SVGImageView
        android:id="@+id/bankLogoView"
        style="@style/icon_account_view"
        app:svg="@drawable/ic_buy_violet"/>

在我的持有人之后是这样的:

bankLogoView.setImageAsset("wallet.svg")

但是我如何从服务器下载 .svg 文件?

最佳答案

我的代码是用 Java 编写的,但希望您能收到备忘录。将以下依赖项添加到您的应用程序模块 build.gradle 文件中:

implementation 'com.caverock:androidsvg:1.2.1'

在你的 GlideModule 中:

public class GlideModule extends AppGlideModule {
    ...
    @Override
    public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
        registry.register(SVG.class, PictureDrawable.class, new SvgDrawableTranscoder()).append(InputStream.class, SVG.class, new SvgDecoder());
    }
}

SvgDecoder.java

public class SvgDecoder implements ResourceDecoder<InputStream, SVG> {

    @Override
    public boolean handles(InputStream source, Options options) throws IOException {
        // TODO: Can we tell?
        return true;
    }

    public Resource<SVG> decode(InputStream source, int width, int height, Options options)
            throws IOException {
        try {
            SVG svg = SVG.getFromInputStream(source);
            return new SimpleResource<SVG>(svg);
        } catch (SVGParseException ex) {
            throw new IOException("Cannot load SVG from stream", ex);
        }
    }
}

SvgDrawableTranscoder.java

public class SvgDrawableTranscoder implements ResourceTranscoder<SVG, PictureDrawable> {
    @Override
    public Resource<PictureDrawable> transcode(Resource<SVG> toTranscode, Options options) {
        SVG svg = toTranscode.get();
        Picture picture = svg.renderToPicture();
        PictureDrawable drawable = new PictureDrawable(picture);
        return new SimpleResource<PictureDrawable>(drawable);
    }
}

SvgSoftwareLayerSetter.java

public class SvgSoftwareLayerSetter implements RequestListener<PictureDrawable> {

    @Override
    public boolean onLoadFailed(GlideException e, Object model, Target<PictureDrawable> target,
                                boolean isFirstResource) {
        ImageView view = ((ImageViewTarget<?>) target).getView();
        view.setLayerType(ImageView.LAYER_TYPE_NONE, null);
        return false;
    }

    @Override
    public boolean onResourceReady(PictureDrawable resource, Object model,
                                   Target<PictureDrawable> target, DataSource dataSource, boolean isFirstResource) {
        ImageView view = ((ImageViewTarget<?>) target).getView();
        view.setLayerType(ImageView.LAYER_TYPE_SOFTWARE, null);
        return false;
    }
}

然后像这样在 Glide 中使用它:

Glide.with(this)
        .as(PictureDrawable.class)
        .load(svgUrl)
        .listener(new SvgSoftwareLayerSetter())
        .into(imageView);

关于android - 无法在 Android 上加载 svg 资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52481007/

相关文章:

kotlin - 将列表分成几部分

android - 在回收者 View 中加载大量项目

android - 签署 APK : Failure [INSTALL_FAILED_DEXOPT]. 。更新

kotlin - 如何将字符串映射到函数并稍后调用它

Android 无法序列化 Kotlin lambda

java - 在 glide 中处理 IllegalArgumentException ("You cannot start a load for a destroyed activity")的最佳方法是什么?

android - 如何使用具有相同 url 的新图像缓存图像?

android - 无法让 Android 应用程序在平板电脑上运行

android - 使用自定义后端检查和播放应用程序完整性

android - 无法使用 android sdk 和 eclipse 解析 'adb version' 的输出