Implement configuration for image loading
We support just two variables in the configuration: gravity and width. Image will be place left, center or right aligned, and width will be WRAP_CONTENT or MATCH_PARENT
This commit is contained in:
		
							parent
							
								
									23d7c09f27
								
							
						
					
					
						commit
						a77c84a30c
					
				@ -36,6 +36,7 @@ import okhttp3.Response;
 | 
			
		||||
import okhttp3.ResponseBody;
 | 
			
		||||
import pl.droidsonroids.gif.GifDrawable;
 | 
			
		||||
import ru.noties.markwon.spans.AsyncDrawable;
 | 
			
		||||
import ru.noties.markwon.spans.configuration.image.ImageConfig;
 | 
			
		||||
 | 
			
		||||
public class AsyncDrawableLoader implements AsyncDrawable.Loader {
 | 
			
		||||
 | 
			
		||||
@ -58,6 +59,7 @@ public class AsyncDrawableLoader implements AsyncDrawable.Loader {
 | 
			
		||||
    private final ExecutorService executorService;
 | 
			
		||||
    private final Handler mainThread;
 | 
			
		||||
    private final Drawable errorDrawable;
 | 
			
		||||
    private final ImageConfig imageConfig;
 | 
			
		||||
 | 
			
		||||
    private final Map<String, Future<?>> requests;
 | 
			
		||||
 | 
			
		||||
@ -67,6 +69,7 @@ public class AsyncDrawableLoader implements AsyncDrawable.Loader {
 | 
			
		||||
        this.executorService = builder.executorService;
 | 
			
		||||
        this.mainThread = new Handler(Looper.getMainLooper());
 | 
			
		||||
        this.errorDrawable = builder.errorDrawable;
 | 
			
		||||
        this.imageConfig = builder.imageConfig;
 | 
			
		||||
        this.requests = new HashMap<>(3);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -146,7 +149,7 @@ public class AsyncDrawableLoader implements AsyncDrawable.Loader {
 | 
			
		||||
                        public void run() {
 | 
			
		||||
                            final AsyncDrawable asyncDrawable = reference.get();
 | 
			
		||||
                            if (asyncDrawable != null && asyncDrawable.isAttached()) {
 | 
			
		||||
                                asyncDrawable.setResult(out);
 | 
			
		||||
                                asyncDrawable.setResult(out, imageConfig);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
@ -345,6 +348,7 @@ public class AsyncDrawableLoader implements AsyncDrawable.Loader {
 | 
			
		||||
        private Resources resources;
 | 
			
		||||
        private ExecutorService executorService;
 | 
			
		||||
        private Drawable errorDrawable;
 | 
			
		||||
        private ImageConfig imageConfig;
 | 
			
		||||
 | 
			
		||||
        public Builder client(@NonNull OkHttpClient client) {
 | 
			
		||||
            this.client = client;
 | 
			
		||||
@ -366,6 +370,11 @@ public class AsyncDrawableLoader implements AsyncDrawable.Loader {
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Builder imageConfig(ImageConfig imageConfig) {
 | 
			
		||||
            this.imageConfig = imageConfig;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AsyncDrawableLoader build() {
 | 
			
		||||
            if (client == null) {
 | 
			
		||||
                client = new OkHttpClient();
 | 
			
		||||
@ -377,6 +386,9 @@ public class AsyncDrawableLoader implements AsyncDrawable.Loader {
 | 
			
		||||
                // we will use executor from okHttp
 | 
			
		||||
                executorService = client.dispatcher().executorService();
 | 
			
		||||
            }
 | 
			
		||||
            if(imageConfig == null){
 | 
			
		||||
                imageConfig = new ImageConfig();
 | 
			
		||||
            }
 | 
			
		||||
            return new AsyncDrawableLoader(this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -12,25 +12,26 @@ import android.support.annotation.Nullable;
 | 
			
		||||
 | 
			
		||||
import ru.noties.markwon.renderer.html.ImageSize;
 | 
			
		||||
import ru.noties.markwon.renderer.html.ImageSizeResolver;
 | 
			
		||||
import ru.noties.markwon.spans.configuration.image.ImageConfig;
 | 
			
		||||
import ru.noties.markwon.spans.configuration.image.ImageGravity;
 | 
			
		||||
import ru.noties.markwon.spans.configuration.image.ImageWidth;
 | 
			
		||||
 | 
			
		||||
public class AsyncDrawable extends Drawable {
 | 
			
		||||
 | 
			
		||||
    public interface Loader {
 | 
			
		||||
 | 
			
		||||
        void load(@NonNull String destination, @NonNull AsyncDrawable drawable);
 | 
			
		||||
 | 
			
		||||
        void cancel(@NonNull String destination);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private final String destination;
 | 
			
		||||
 | 
			
		||||
    private final Loader loader;
 | 
			
		||||
 | 
			
		||||
    private final ImageSize imageSize;
 | 
			
		||||
 | 
			
		||||
    private final ImageSizeResolver imageSizeResolver;
 | 
			
		||||
 | 
			
		||||
    private Drawable result;
 | 
			
		||||
 | 
			
		||||
    private Callback callback;
 | 
			
		||||
 | 
			
		||||
    private int canvasWidth;
 | 
			
		||||
 | 
			
		||||
    private float textSize;
 | 
			
		||||
 | 
			
		||||
    public AsyncDrawable(@NonNull String destination, @NonNull Loader loader) {
 | 
			
		||||
@ -41,10 +42,10 @@ public class AsyncDrawable extends Drawable {
 | 
			
		||||
     * @since 1.0.1
 | 
			
		||||
     */
 | 
			
		||||
    public AsyncDrawable(
 | 
			
		||||
            @NonNull String destination,
 | 
			
		||||
            @NonNull Loader loader,
 | 
			
		||||
            @Nullable ImageSizeResolver imageSizeResolver,
 | 
			
		||||
            @Nullable ImageSize imageSize
 | 
			
		||||
        @NonNull String destination,
 | 
			
		||||
        @NonNull Loader loader,
 | 
			
		||||
        @Nullable ImageSizeResolver imageSizeResolver,
 | 
			
		||||
        @Nullable ImageSize imageSize
 | 
			
		||||
    ) {
 | 
			
		||||
        this.destination = destination;
 | 
			
		||||
        this.loader = loader;
 | 
			
		||||
@ -91,7 +92,7 @@ public class AsyncDrawable extends Drawable {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setResult(@NonNull Drawable result) {
 | 
			
		||||
    public void setResult(@NonNull Drawable result, @NonNull ImageConfig imageConfig) {
 | 
			
		||||
 | 
			
		||||
        // if we have previous one, detach it
 | 
			
		||||
        if (this.result != null) {
 | 
			
		||||
@ -101,7 +102,7 @@ public class AsyncDrawable extends Drawable {
 | 
			
		||||
        this.result = result;
 | 
			
		||||
        this.result.setCallback(callback);
 | 
			
		||||
 | 
			
		||||
        final Rect bounds = resolveBounds();
 | 
			
		||||
        final Rect bounds = resolveBounds(imageConfig);
 | 
			
		||||
        result.setBounds(bounds);
 | 
			
		||||
        setBounds(bounds);
 | 
			
		||||
 | 
			
		||||
@ -168,17 +169,55 @@ public class AsyncDrawable extends Drawable {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param imageConfig
 | 
			
		||||
     * @since 1.0.1
 | 
			
		||||
     */
 | 
			
		||||
    @NonNull
 | 
			
		||||
    private Rect resolveBounds() {
 | 
			
		||||
    private Rect resolveBounds(@NonNull ImageConfig imageConfig) {
 | 
			
		||||
        final Rect rect;
 | 
			
		||||
        if (imageSizeResolver == null
 | 
			
		||||
                || imageSize == null) {
 | 
			
		||||
            || imageSize == null) {
 | 
			
		||||
            rect = result.getBounds();
 | 
			
		||||
        } else {
 | 
			
		||||
            rect = imageSizeResolver.resolveImageSize(imageSize, result.getBounds(), canvasWidth, textSize);
 | 
			
		||||
        }
 | 
			
		||||
        return rect;
 | 
			
		||||
        return adjustBounds(rect, imageConfig);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Rect adjustBounds(Rect bounds, ImageConfig imageConfig) {
 | 
			
		||||
        final ImageGravity gravity = imageConfig.getGravity();
 | 
			
		||||
        final ImageWidth imageWidth = imageConfig.getImageWidth();
 | 
			
		||||
 | 
			
		||||
        if (imageWidth == ImageWidth.MatchParent) {
 | 
			
		||||
            final float aspectRatio = (float) bounds.width() / bounds.height();
 | 
			
		||||
            bounds.left = 0;
 | 
			
		||||
            bounds.right = canvasWidth;
 | 
			
		||||
            bounds.bottom = (int) (bounds.top + bounds.height() * aspectRatio);
 | 
			
		||||
        } else {
 | 
			
		||||
            switch (gravity) {
 | 
			
		||||
                case Left:
 | 
			
		||||
                    //left is unchanged
 | 
			
		||||
                    break;
 | 
			
		||||
                case Right:
 | 
			
		||||
                    bounds.left = canvasWidth - bounds.width();
 | 
			
		||||
                    bounds.right = canvasWidth;
 | 
			
		||||
                    break;
 | 
			
		||||
                case Center:
 | 
			
		||||
                    final int center = canvasWidth / 2;
 | 
			
		||||
                    final int imageRadius = bounds.width() / 2;
 | 
			
		||||
                    bounds.left = center - imageRadius;
 | 
			
		||||
                    bounds.right = center + imageRadius;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return bounds;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface Loader {
 | 
			
		||||
 | 
			
		||||
        void load(@NonNull String destination, @NonNull AsyncDrawable drawable);
 | 
			
		||||
 | 
			
		||||
        void cancel(@NonNull String destination);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,25 @@
 | 
			
		||||
package ru.noties.markwon.spans.configuration.image
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Configuration for images
 | 
			
		||||
 *
 | 
			
		||||
 * Can set two parameters: image width style and horizontal gravity
 | 
			
		||||
 *
 | 
			
		||||
 * @property imageWidth Width of the image to be displayed (WRAP_CONTENT or MATCH_PARENT)
 | 
			
		||||
 * @property gravity Horizontal gravity (left, right or center)
 | 
			
		||||
 */
 | 
			
		||||
class ImageConfig @JvmOverloads constructor(
 | 
			
		||||
        val imageWidth: ImageWidth = ImageWidth.Wrap,
 | 
			
		||||
        val gravity: ImageGravity = ImageGravity.Left
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
enum class ImageGravity {
 | 
			
		||||
    Left,
 | 
			
		||||
    Center,
 | 
			
		||||
    Right
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum class ImageWidth {
 | 
			
		||||
    Wrap,
 | 
			
		||||
    MatchParent
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user