12/08/2018, 16:19

Load ảnh SVG từ sever với Androidsvg kết hợp với Glide

Xin chào mọi người, hôm trước mình gặp 1 bài toán là load 1 file ảnh từ sever về và hiển thị lên Imageview. Nhưng ảnh đó lại là ảnh svg. Ngồi hì hục mãi, cứ ngỡ là chỉ cần Glide là có thể load được lên như ảnh thường, lỗi này cũng do mình hơi chủ quan không xem lại document của glide. Sau 1 hồi ...

Xin chào mọi người, hôm trước mình gặp 1 bài toán là load 1 file ảnh từ sever về và hiển thị lên Imageview. Nhưng ảnh đó lại là ảnh svg. Ngồi hì hục mãi, cứ ngỡ là chỉ cần Glide là có thể load được lên như ảnh thường, lỗi này cũng do mình hơi chủ quan không xem lại document của glide. Sau 1 hồi loay hoay thì cũng tìm ra cách để xử lý đó là kết hợp Glide với Android svg. Đầu tiên , bạn thêm thư viện vào gradle

    compile 'com.github.bumptech.glide:glide:4.1.1'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.1.1'
    compile 'com.caverock:androidsvg:1.2.0'

Sau khi thêm thư viện xong, bạn phải tạo thêm các file sau để có thể load được ảnh lên:

  1. Tạo class SvgDecode làm nhiệm vụ decode ảnh có định dạng svg, có nội dung sau:
  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 awidth, 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);
        }
    }
}


  1. Tạo class SvgDrawableTranscoder để transcode ảnh svg đó
public class SvgDrawableTranscoder implements ResourceTranscoder<SVG, PictureDrawable> {
    @Override
    public Resource<PictureDrawable> transcode(Resource<SVG> toTranscode) {
        SVG svg = toTranscode.get();
        Picture picture = svg.renderToPicture();
        PictureDrawable drawable = new PictureDrawable(picture);
        return new SimpleResource<PictureDrawable>(drawable);
    }
}

  1. Tạo class Svg modul extend AppGlideModule
@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());
    }

    // Disable manifest parsing to avoid adding similar modules twice.
    @Override
    public boolean isManifestParsingEnabled() {
        return false;
    }
}

  1. Tạo class SvgSoftwareLayerSetter implement RequestListener<PictureDrawable>
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;
  }
}
  1. Cuối cùng là việc đơn giản nhât chỉ cần load ảnh là xong :man_detective:
@BindingAdapter("logoClup")
    public static void setLogoClup(ImageView view, String path) {
        if (path != null && path.endsWith("svg")) {
            RequestBuilder<PictureDrawable> requestBuilder;
            requestBuilder = Glide.with(view.getContext())
                    .as(PictureDrawable.class)
                    .transition(withCrossFade())
                    .listener(new SvgSoftwareLayerSetter());
            Uri uri = Uri.parse(path);
            requestBuilder.load(uri).into(view);
        } else {
            Glide.with(view.getContext()).load(path).into(view);
        }
    }

Cũng khá phức tạp để load ảnh svg từ sever về đúng không ạ? Rất mong góp ý từ các bạn để bài viết thêm hoàn thiện Source : https://gitlab.com/nv94/football Bài viết được tham khảo từ https://github.com/bumptech/glide

0