Merge pull request #174 from tylerbwong/image-coil
Add CoilImagesPlugin Module
This commit is contained in:
commit
6b9e79ce5e
@ -72,7 +72,8 @@ ext {
|
|||||||
'adapt' : 'io.noties:adapt:2.0.0',
|
'adapt' : 'io.noties:adapt:2.0.0',
|
||||||
'dagger' : "com.google.dagger:dagger:$daggerVersion",
|
'dagger' : "com.google.dagger:dagger:$daggerVersion",
|
||||||
'picasso' : 'com.squareup.picasso:picasso:2.71828',
|
'picasso' : 'com.squareup.picasso:picasso:2.71828',
|
||||||
'glide' : 'com.github.bumptech.glide:glide:4.9.0'
|
'glide' : 'com.github.bumptech.glide:glide:4.9.0',
|
||||||
|
'coil' : 'io.coil-kt:coil:0.8.0'
|
||||||
]
|
]
|
||||||
|
|
||||||
deps['annotationProcessor'] = [
|
deps['annotationProcessor'] = [
|
||||||
|
35
docs/docs/v4/image-coil/README.md
Normal file
35
docs/docs/v4/image-coil/README.md
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# Image Coil
|
||||||
|
|
||||||
|
<MavenBadge4 :artifact="'image-coil'" />
|
||||||
|
|
||||||
|
Image loading based on `Coil` library
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val markwon = Markwon.builder(context)
|
||||||
|
// automatically create Coil instance
|
||||||
|
.usePlugin(CoilImagesPlugin.create(context))
|
||||||
|
// use supplied ImageLoader instance
|
||||||
|
.usePlugin(CoilImagesPlugin.create(
|
||||||
|
context,
|
||||||
|
ImageLoader(context) {
|
||||||
|
availableMemoryPercentage(0.5)
|
||||||
|
bitmapPoolPercentage(0.5)
|
||||||
|
crossfade(true)
|
||||||
|
}
|
||||||
|
))
|
||||||
|
// if you need more control
|
||||||
|
.usePlugin(CoilImagesPlugin.create(object : CoilImagesPlugin.CoilStore {
|
||||||
|
override fun load(drawable: AsyncDrawable): LoadRequest {
|
||||||
|
return LoadRequest(context, customImageLoader.defaults) {
|
||||||
|
data(drawable.destination)
|
||||||
|
crossfade(true)
|
||||||
|
transformations(CircleCropTransformation())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override cancel(disposable: RequestDisposable) {
|
||||||
|
disposable.dispose()
|
||||||
|
}
|
||||||
|
}, customImageLoader))
|
||||||
|
.build()
|
||||||
|
```
|
3
markwon-image-coil/README.md
Normal file
3
markwon-image-coil/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Images (Coil)
|
||||||
|
|
||||||
|
https://noties.io/Markwon/docs/v4/image-coil/
|
21
markwon-image-coil/build.gradle
Normal file
21
markwon-image-coil/build.gradle
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
|
android {
|
||||||
|
|
||||||
|
compileSdkVersion config['compile-sdk']
|
||||||
|
buildToolsVersion config['build-tools']
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion config['min-sdk']
|
||||||
|
targetSdkVersion config['target-sdk']
|
||||||
|
versionCode 1
|
||||||
|
versionName version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api project(':markwon-core')
|
||||||
|
api deps['coil']
|
||||||
|
}
|
||||||
|
|
||||||
|
registerArtifact(this)
|
4
markwon-image-coil/gradle.properties
Normal file
4
markwon-image-coil/gradle.properties
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
POM_NAME=Image Coil
|
||||||
|
POM_ARTIFACT_ID=image-coil
|
||||||
|
POM_DESCRIPTION=Markwon image loading module (based on Coil library)
|
||||||
|
POM_PACKAGING=aar
|
1
markwon-image-coil/src/main/AndroidManifest.xml
Normal file
1
markwon-image-coil/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<manifest package="io.noties.markwon.image.coil" />
|
@ -0,0 +1,187 @@
|
|||||||
|
package io.noties.markwon.image.coil;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.text.Spanned;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.commonmark.node.Image;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import coil.Coil;
|
||||||
|
import coil.ImageLoader;
|
||||||
|
import coil.api.ImageLoaders;
|
||||||
|
import coil.request.LoadRequest;
|
||||||
|
import coil.request.RequestDisposable;
|
||||||
|
import coil.target.Target;
|
||||||
|
import io.noties.markwon.AbstractMarkwonPlugin;
|
||||||
|
import io.noties.markwon.MarkwonConfiguration;
|
||||||
|
import io.noties.markwon.MarkwonSpansFactory;
|
||||||
|
import io.noties.markwon.image.AsyncDrawable;
|
||||||
|
import io.noties.markwon.image.AsyncDrawableLoader;
|
||||||
|
import io.noties.markwon.image.AsyncDrawableScheduler;
|
||||||
|
import io.noties.markwon.image.DrawableUtils;
|
||||||
|
import io.noties.markwon.image.ImageSpanFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 4.0.0
|
||||||
|
* @author Tyler Wong
|
||||||
|
*/
|
||||||
|
public class CoilImagesPlugin extends AbstractMarkwonPlugin {
|
||||||
|
|
||||||
|
public interface CoilStore {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
LoadRequest load(@NonNull AsyncDrawable drawable);
|
||||||
|
|
||||||
|
void cancel(@NonNull RequestDisposable disposable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static CoilImagesPlugin create(@NonNull final Context context) {
|
||||||
|
return create(new CoilStore() {
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public LoadRequest load(@NonNull AsyncDrawable drawable) {
|
||||||
|
return ImageLoaders.newLoadBuilder(Coil.loader(), context)
|
||||||
|
.data(drawable.getDestination())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel(@NonNull RequestDisposable disposable) {
|
||||||
|
disposable.dispose();
|
||||||
|
}
|
||||||
|
}, Coil.loader());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static CoilImagesPlugin create(@NonNull final Context context,
|
||||||
|
@NonNull final ImageLoader imageLoader) {
|
||||||
|
return create(new CoilStore() {
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public LoadRequest load(@NonNull AsyncDrawable drawable) {
|
||||||
|
return ImageLoaders.newLoadBuilder(imageLoader, context)
|
||||||
|
.data(drawable.getDestination())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel(@NonNull RequestDisposable disposable) {
|
||||||
|
disposable.dispose();
|
||||||
|
}
|
||||||
|
}, imageLoader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public static CoilImagesPlugin create(@NonNull final CoilStore coilStore,
|
||||||
|
@NonNull final ImageLoader imageLoader) {
|
||||||
|
return new CoilImagesPlugin(coilStore, imageLoader);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final CoilAsyncDrawableLoader coilAsyncDrawableLoader;
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
CoilImagesPlugin(@NonNull CoilStore coilStore, @NonNull ImageLoader imageLoader) {
|
||||||
|
this.coilAsyncDrawableLoader = new CoilAsyncDrawableLoader(coilStore, imageLoader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureSpansFactory(@NonNull MarkwonSpansFactory.Builder builder) {
|
||||||
|
builder.setFactory(Image.class, new ImageSpanFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) {
|
||||||
|
builder.asyncDrawableLoader(coilAsyncDrawableLoader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) {
|
||||||
|
AsyncDrawableScheduler.unschedule(textView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterSetText(@NonNull TextView textView) {
|
||||||
|
AsyncDrawableScheduler.schedule(textView);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class CoilAsyncDrawableLoader extends AsyncDrawableLoader {
|
||||||
|
|
||||||
|
private final CoilStore coilStore;
|
||||||
|
private final ImageLoader imageLoader;
|
||||||
|
private final Map<AsyncDrawable, RequestDisposable> cache = new HashMap<>(2);
|
||||||
|
|
||||||
|
CoilAsyncDrawableLoader(@NonNull CoilStore coilStore, @NonNull ImageLoader imageLoader) {
|
||||||
|
this.coilStore = coilStore;
|
||||||
|
this.imageLoader = imageLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(@NonNull AsyncDrawable drawable) {
|
||||||
|
final Target target = new AsyncDrawableTarget(drawable);
|
||||||
|
LoadRequest request = coilStore.load(drawable).newBuilder()
|
||||||
|
.target(target)
|
||||||
|
.build();
|
||||||
|
RequestDisposable disposable = imageLoader.load(request);
|
||||||
|
cache.put(drawable, disposable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel(@NonNull AsyncDrawable drawable) {
|
||||||
|
final RequestDisposable disposable = cache.remove(drawable);
|
||||||
|
if (disposable != null) {
|
||||||
|
coilStore.cancel(disposable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Drawable placeholder(@NonNull AsyncDrawable drawable) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AsyncDrawableTarget implements Target {
|
||||||
|
|
||||||
|
private final AsyncDrawable drawable;
|
||||||
|
|
||||||
|
AsyncDrawableTarget(@NonNull AsyncDrawable drawable) {
|
||||||
|
this.drawable = drawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccess(@NonNull Drawable loadedDrawable) {
|
||||||
|
if (cache.remove(drawable) != null) {
|
||||||
|
if (drawable.isAttached()) {
|
||||||
|
DrawableUtils.applyIntrinsicBoundsIfEmpty(loadedDrawable);
|
||||||
|
drawable.setResult(loadedDrawable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart(@Nullable Drawable placeholder) {
|
||||||
|
if (placeholder != null && drawable.isAttached()) {
|
||||||
|
DrawableUtils.applyIntrinsicBoundsIfEmpty(placeholder);
|
||||||
|
drawable.setResult(placeholder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@Nullable Drawable errorDrawable) {
|
||||||
|
if (cache.remove(drawable) != null) {
|
||||||
|
if (errorDrawable != null && drawable.isAttached()) {
|
||||||
|
DrawableUtils.applyIntrinsicBoundsIfEmpty(errorDrawable);
|
||||||
|
drawable.setResult(errorDrawable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -82,6 +82,7 @@ public class RecyclerActivity extends Activity {
|
|||||||
// }))
|
// }))
|
||||||
.usePlugin(PicassoImagesPlugin.create(context))
|
.usePlugin(PicassoImagesPlugin.create(context))
|
||||||
// .usePlugin(GlideImagesPlugin.create(context))
|
// .usePlugin(GlideImagesPlugin.create(context))
|
||||||
|
// .usePlugin(CoilImagesPlugin.create(context))
|
||||||
// important to use TableEntryPlugin instead of TablePlugin
|
// important to use TableEntryPlugin instead of TablePlugin
|
||||||
.usePlugin(TableEntryPlugin.create(context))
|
.usePlugin(TableEntryPlugin.create(context))
|
||||||
.usePlugin(HtmlPlugin.create())
|
.usePlugin(HtmlPlugin.create())
|
||||||
|
@ -8,6 +8,7 @@ include ':app', ':sample',
|
|||||||
':markwon-ext-tasklist',
|
':markwon-ext-tasklist',
|
||||||
':markwon-html',
|
':markwon-html',
|
||||||
':markwon-image',
|
':markwon-image',
|
||||||
|
':markwon-image-coil',
|
||||||
':markwon-image-glide',
|
':markwon-image-glide',
|
||||||
':markwon-image-picasso',
|
':markwon-image-picasso',
|
||||||
':markwon-linkify',
|
':markwon-linkify',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user