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',
|
||||
'dagger' : "com.google.dagger:dagger:$daggerVersion",
|
||||
'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'] = [
|
||||
|
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(GlideImagesPlugin.create(context))
|
||||
// .usePlugin(CoilImagesPlugin.create(context))
|
||||
// important to use TableEntryPlugin instead of TablePlugin
|
||||
.usePlugin(TableEntryPlugin.create(context))
|
||||
.usePlugin(HtmlPlugin.create())
|
||||
|
@ -8,6 +8,7 @@ include ':app', ':sample',
|
||||
':markwon-ext-tasklist',
|
||||
':markwon-html',
|
||||
':markwon-image',
|
||||
':markwon-image-coil',
|
||||
':markwon-image-glide',
|
||||
':markwon-image-picasso',
|
||||
':markwon-linkify',
|
||||
|
Loading…
x
Reference in New Issue
Block a user