noties / Markwon

Android markdown library (no WebView)
https://noties.io/Markwon/
Apache License 2.0
2.68k stars 298 forks source link

Change error drawable size #439

Open alexxkovalchuk opened 1 year ago

alexxkovalchuk commented 1 year ago
  1. Please specify expected/actual behavior

I am using the AbstractMarkwonPlugin to make an image full width, also I am using the ErrorHandler. It seems to me that they conflict with each other, because the error drawable is also displayed in full width. I want to note that this does not happen with the PlaceholderProvider.

  1. Please specify conditions/steps to reproduce (layout, code, markdown used, etc)
String md = "![](https://www.example.com/images/abc.png)";

Markwon markwon = Markwon.builder(context)
.usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
            @Override
            public void configureImages(@NonNull ImagesPlugin plugin) {
                plugin.errorHandler(new ImagesPlugin.ErrorHandler() {
                    @Nullable
                    @Override
                    public Drawable handleError(@NonNull String url, @NonNull Throwable throwable) {
                        Drawable brokenImg = ContextCompat.getDrawable(context, R.drawable.icon_broken_img);
                        brokenImg.setBounds(0, 0, 48, 48);
                        return brokenImg;
                    }
                });
            }
        }))
.usePlugin(new AbstractMarkwonPlugin() {
    @Override
    public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {
        builder.setFactory(Image.class, (configuration, props) ->
                new AsyncDrawableSpan(configuration.theme(),
                        new AsyncDrawable(
                                ImageProps.DESTINATION.require(props),
                                configuration.asyncDrawableLoader(),
                                configuration.imageSizeResolver(),
                                imageSize(props)
                        ),
                        AsyncDrawableSpan.ALIGN_BOTTOM,
                        ImageProps.REPLACEMENT_TEXT_IS_LINK.get(props, false)
                ));
    }
})
.build();

@NonNull
private ImageSize imageSize(@NonNull RenderProps props) {
    final ImageSize imageSize = ImageProps.IMAGE_SIZE.get(props);
    if (imageSize != null) {
        return imageSize;
    }
    return new ImageSize(new ImageSize.Dimension(100F, "%"), null);
}

With the PlaceholderProvider everything looks good.

.usePlugin(ImagesPlugin.create(new ImagesPlugin.ImagesConfigure() {
    @Override
    public void configureImages(@NonNull ImagesPlugin plugin) {
        plugin.placeholderProvider(new ImagesPlugin.PlaceholderProvider() {
            @Nullable
            @Override
            public Drawable providePlaceholder(@NonNull AsyncDrawable drawable) {
                Drawable brokenImg = ContextCompat.getDrawable(context, R.drawable.icon_broken_img);
                brokenImg.setBounds(0, 0, 48, 48);
                return brokenImg;
            }
        });
    }
}))
noties commented 1 year ago

Hello @alexxkovalchuk ,

in default image loading plugin, error drawable has no special meaning, it is just a replacement for a failed image. So it goes through all the process - including the ImageSize resolving. In your snippet 100% width is applied, so it is applied to both normal image and error image.

As a workaround, you can create a wrapper drawable that would consume all available bounds, but inside would position error drawable according to your logic