Glide加载SVG图片:从网络到显示的完整流程

Glide加载SVG图片:从网络到显示的完整流程

【免费下载链接】glide An image loading and caching library for Android focused on smooth scrolling 【免费下载链接】glide 项目地址: https://gitcode.com/gh_mirrors/gl/glide

在Android应用开发中,SVG(Scalable Vector Graphics)图片凭借其无损缩放特性,成为图标和简单图形的理想选择。本文将以Glide图片加载库为例,详细讲解如何从网络或本地资源加载并显示SVG图片,包含完整实现流程和关键代码解析。

开发准备与项目结构

SVG加载功能位于Glide示例项目的svg模块中,核心文件结构如下:

samples/svg/src/main/java/com/bumptech/glide/samples/svg/
├── MainActivity.java       // 主界面,展示SVG加载示例
├── SvgModule.java          // Glide模块配置,注册SVG解码器
├── SvgDecoder.java         // SVG解析器,将输入流转换为SVG对象
├── SvgDrawableTranscoder.java  // 将SVG转换为Drawable
└── SvgSoftwareLayerSetter.java // 设置ImageView的软件渲染层

布局文件位于samples/svg/src/main/res/layout/activity_main.xml,包含两个ImageView分别用于显示本地资源和网络SVG图片。

核心组件实现

1. Glide模块配置(SvgModule)

要让Glide支持SVG格式,需通过AppGlideModule注册自定义解码器和转换器。SvgModule.java实现了这一功能:

@GlideModule
public class SvgModule extends AppGlideModule {
  @Override
  public void registerComponents(Context context, Glide glide, Registry registry) {
    registry
      .register(SVG.class, PictureDrawable.class, new SvgDrawableTranscoder())
      .append(InputStream.class, SVG.class, new SvgDecoder());
  }
  
  @Override
  public boolean isManifestParsingEnabled() {
    return false; // 禁用Manifest解析,避免重复注册
  }
}

这段代码完成了两件关键工作:

  • 通过append()添加SvgDecoder,使Glide能将输入流解析为SVG对象
  • 通过register()添加SvgDrawableTranscoder,实现SVG到PictureDrawable的转换

2. SVG解码器(SvgDecoder)

SvgDecoder.java负责将输入流解析为AndroidSVG库的SVG对象:

public class SvgDecoder implements ResourceDecoder<InputStream, SVG> {
  @Override
  public Resource<SVG> decode(InputStream source, int width, int height, Options options) {
    try {
      SVG svg = SVG.getFromInputStream(source);
      // 设置SVG视口大小以匹配目标尺寸
      if (width > 0 && height > 0) {
        svg.setDocumentWidth(width);
        svg.setDocumentHeight(height);
      }
      return new SimpleResource<>(svg);
    } catch (Exception e) {
      throw new RuntimeException("Failed to decode SVG", e);
    }
  }
  
  @Override
  public boolean handles(InputStream source, Options options) {
    // 这里可以根据文件头判断是否为SVG
    return true;
  }
}

3. 转码器与渲染设置

SvgDrawableTranscoder.java将SVG对象转换为可绘制的PictureDrawable:

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<>(drawable);
  }
}

由于SVG渲染需要软件加速支持,SvgSoftwareLayerSetter.java通过RequestListener设置ImageView的图层类型:

public class SvgSoftwareLayerSetter implements RequestListener<PictureDrawable> {
  @Override
  public boolean onResourceReady(PictureDrawable resource, Object model, 
                                Target<PictureDrawable> target, 
                                DataSource dataSource, boolean isFirstResource) {
    ImageView imageView = (ImageView) target.getView();
    imageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); // 启用软件渲染
    return false;
  }
}

加载与显示SVG图片

1. 构建Glide请求

MainActivity.java中,首先创建SVG专用的请求构建器:

private RequestBuilder<PictureDrawable> requestBuilder;

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  requestBuilder = GlideApp.with(this)
    .as(PictureDrawable.class)
    .placeholder(R.drawable.image_loading)
    .error(R.drawable.image_error)
    .transition(withCrossFade())
    .listener(new SvgSoftwareLayerSetter());
}

2. 加载本地资源SVG

从raw目录加载SVG资源的实现:

private void loadRes() {
  Uri uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE 
    + "://" + getPackageName() + "/" + R.raw.android_toy_h);
  requestBuilder.load(uri).into(imageViewRes);
}

项目提供了多个SVG示例资源,位于samples/svg/src/main/res/raw/目录下,如android_toy_h.svg等。

3. 加载网络SVG

从网络URL加载SVG的实现:

private void loadNet() {
  Uri uri = Uri.parse("http://www.clker.com/cliparts/u/Z/2/b/a/6/android-toy-h.svg");
  requestBuilder.load(uri).into(imageViewNet);
}

注意:加载网络资源需要在AndroidManifest.xml中添加网络权限:

<uses-permission android:name="android.permission.INTERNET" />

运行效果与缓存管理

界面展示

运行svg示例后,主界面会显示两个SVG图片:

  • 左侧:从本地raw资源加载的SVG
  • 右侧:从网络加载的SVG

SVG加载示例界面

注:实际运行时image_loading会被真实SVG替换,此处为占位图示意

缓存控制

MainActivity提供了清除缓存的功能,通过以下代码实现:

public void clearCache(View v) {
  GlideRequests glideRequests = GlideApp.with(this);
  glideRequests.clear(imageViewRes);
  glideRequests.clear(imageViewNet);
  GlideApp.get(this).clearMemory();
  
  // 清除磁盘缓存
  File cacheDir = Preconditions.checkNotNull(Glide.getPhotoCacheDir(this));
  if (cacheDir.isDirectory()) {
    for (File child : cacheDir.listFiles()) {
      child.delete();
    }
  }
  reload();
}

常见问题解决

1. 图片显示空白或模糊

  • 确保已设置软件渲染层:imageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
  • 检查SVG文件是否有效,可先用浏览器打开测试
  • 确认目标ImageView尺寸设置合理,避免过度缩放

2. 解码失败异常

  • 检查AndroidSVG库是否正确集成
  • 确保输入流未提前关闭
  • 对于大型SVG,考虑增加Glide的内存缓存限制
GlideBuilder builder = new GlideBuilder();
builder.setMemoryCache(new LruResourceCache(20 * 1024 * 1024)); // 20MB缓存

3. 网络加载缓慢

  • 实现渐进式加载,先显示低分辨率占位图
  • 配置Glide的超时参数:.timeout(10000)
  • 启用磁盘缓存:默认已启用,可通过diskCacheStrategy()调整策略

总结与扩展

通过本文介绍的方法,我们实现了使用Glide加载和显示SVG图片的完整流程。核心是通过Glide的扩展机制,注册自定义的解码器和转换器,将SVG格式整合到Glide的加载流程中。

功能扩展建议

  1. 添加SVG颜色动态修改功能,通过AndroidSVG的API可以在加载时修改SVG颜色:
SVG svg = SVG.getFromInputStream(inputStream);
svg.getDocument().setFillColor(Color.RED);
  1. 实现SVG动画效果,结合属性动画改变SVG的缩放、旋转等属性。

  2. 优化内存使用,对于大型SVG可考虑使用renderToPicture(int width, int height)指定渲染尺寸。

完整示例代码可参考Glide项目的svg模块,该实现已在多个Android版本上测试通过,兼容API 15及以上系统版本。

【免费下载链接】glide An image loading and caching library for Android focused on smooth scrolling 【免费下载链接】glide 项目地址: https://gitcode.com/gh_mirrors/gl/glide

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值