Images
WARNING
This is documentation for legacy versions. For the most current version click here.
Starting with 3.0.0 Markwon
comes with ImagesPlugin
which supports http(s)
, file
and data
schemes and default media
decoder (for simple images, no SVG or GIF which
are defined in standalone modules).
ImagesPlugin
ImagePlugin
takes care of obtaining image resource, decoding it and displaying it in a TextView
.
WARNING
Although core
artifact contains ImagesPlugin
one must
still explicitly register the ImagesPlugin
on resulting Markwon
instance.
final Markwon markwon = Markwon.builder(context)
.usePlugin(ImagesPlugin.create())
There are 2 factory methods to obtain ImagesPlugin
:
ImagesPlugin#create(Context)
ImagesPlugin#createWithAssets(Context)
The first one #create(Context)
configures:
FileSchemeHandler
that allows obtaining images fromfile://
urisDataUriSchemeHandler
that allows inlining images withdata:
scheme (data:image/svg+xml;base64,MTIz
)NetworkSchemeHandler
that allows obtaining images fromhttp://
andhttps://
uris (internally it usesHttpURLConnection
)ImageMediaDecoder
which tries to decode all encountered images as regular ones (png, jpg, etc)
The second one #createWithAssets(Context)
does the same but also adds support
for images that reside in assets
folder of your application and
referenced by file:///android_asset/{path}
uri.
ImagesPlugin
also prepares a TextView to display images. Due to asynchronous
nature of image loading, there must be a way to invalidate resulting Spanned
content after an image is loaded.
WARNING
Images come with few limitations. For of all, they work with a TextView only.
This is due to the fact that there is no way to invalidate a Spanned
content
by itself (without context in which it is displayed). So, if Markwon
is used,
for example, to display a Toast
with an image:
final Spanned spanned = markwon.toMarkdown("Hello ![alt](https://my.image/1.JPG)");
Toast.makeText(context, spanned, Toast.LENGTH_LONG).show();
Image probably won't be displayed. As a workaround for Toast
a custom View
can be used:
final Spanned spanned = markwon.toMarkdown("Hello ![alt](https://my.image/1.JPG)");
final View view = createToastView();
final TextView textView = view.findViewById(R.id.text_view);
markwon.setParsedMarkdown(textView, spanned);
final Toast toast = new Toast(context);
toast.setView(view);
// other Toast configurations
toast.show();
SchemeHandler
To add support for different schemes (or customize provided) a SchemeHandler
must be used.
final Markwon markwon = Markwon.builder(context)
.usePlugin(ImagesPlugin.create(context))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureImages(@NonNull AsyncDrawableLoader.Builder builder) {
// example only, Markwon doesn't come with a ftp scheme handler
builder.addSchemeHandler("ftp", new FtpSchemeHandler());
}
})
.build();
It's a class to convert an URI into an InputStream
:
public abstract class SchemeHandler {
@Nullable
public abstract ImageItem handle(@NonNull String raw, @NonNull Uri uri);
}
ImageItem
is a holder class for resulting InputStream
and (optional)
content type:
public class ImageItem {
private final String contentType;
private final InputStream inputStream;
/* rest omitted */
}
Based on contentType
returned a corresponding MediaDecoder
will be matched.
If no MediaDecoder
can handle given contentType
then a default media decoder will
be used.
MediaDecoder
By default core
artifact comes with default image decoder only. It's called
ImageMediaDecoder
and it can decode all the formats that BitmapFactory#decodeStream(InputStream)
can.
final Markwon markwon = Markwon.builder(this)
.usePlugin(ImagesPlugin.create(this))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureImages(@NonNull AsyncDrawableLoader.Builder builder) {
builder.addMediaDecoder("text/plain", new TextPlainMediaDecoder());
}
})
.build();
MediaDecoder
is a class to turn InputStream
into a Drawable
:
public abstract class MediaDecoder {
@Nullable
public abstract Drawable decode(@NonNull InputStream inputStream);
}
TIP
If you are using html you do not have to additionally setup
images displayed via <img>
tag, as HtmlPlugin
automatically uses configured
image loader. But images referenced in HTML come with additional support for
sizes, which is not supported natively by markdown, allowing absolute or relative sizes:
<img src="./assets/my-image" width="100%">
3.0.0
Placeholder drawableIt's possible to provide a custom placeholder for an image (whilst it's loading).
final Markwon markwon = Markwon.builder(context)
.usePlugin(ImagesPlugin.create(context))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureImages(@NonNull AsyncDrawableLoader.Builder builder) {
builder.placeholderDrawableProvider(new AsyncDrawableLoader.DrawableProvider() {
@Override
public Drawable provide() {
// your custom placeholder drawable
return new PlaceholderDrawable();
}
});
}
});
3.0.0
Error drawableTo fallback in case of error whilst loading an image, an error drawable
can be used:
final Markwon markwon = Markwon.builder(context)
.usePlugin(ImagesPlugin.create(context))
.usePlugin(new AbstractMarkwonPlugin() {
@Override
public void configureImages(@NonNull AsyncDrawableLoader.Builder builder) {
builder.errorDrawableProvider(new AsyncDrawableLoader.DrawableProvider() {
@Override
public Drawable provide() {
// your custom error drawable
return new MyErrorDrawable();
}
});
}
});
WARNING
Before 3.0.0
AsyncDrawableLoader
accepted a simple Drawable
as error drawable
argument. Starting 3.0.0
it accepts a DrawableProvider
instead.