diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2445fff3..ecce3fae 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,8 @@
* Fix SpannableBuilder `subSequence` method
* Introduce Nougat check in `BulletListItemSpan` to position bullet (for bullets to be
positioned correctly when nested inside other `LeadingMarginSpan`s)
+* Reduced number of invalidations in AsyncDrawable when result is ready
+* AsyncDrawable#hasKnownDimentions -> AsyncDrawable#hasKnownDimensions typo fix
# 4.2.0
* `MarkwonEditor` to highlight markdown input whilst editing (new module: `markwon-editor`)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 9e5a6805..311a39e2 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -4,7 +4,6 @@
package="io.noties.markwon.app">
-
0;
}
/**
- * @see #hasKnownDimentions()
+ * @since 4.2.1-SNAPSHOT
+ */
+ @SuppressWarnings({"unused", "WeakerAccess"})
+ public boolean hasKnownDimensions() {
+ return canvasWidth > 0;
+ }
+
+ /**
+ * @see #hasKnownDimensions()
* @since 4.0.0
*/
public int getLastKnownCanvasWidth() {
@@ -84,9 +98,10 @@ public class AsyncDrawable extends Drawable {
}
/**
- * @see #hasKnownDimentions()
+ * @see #hasKnownDimensions()
* @since 4.0.0
*/
+ @SuppressWarnings("WeakerAccess")
public float getLastKnowTextSize() {
return textSize;
}
@@ -95,6 +110,7 @@ public class AsyncDrawable extends Drawable {
return result;
}
+ @SuppressWarnings("WeakerAccess")
public boolean hasResult() {
return result != null;
}
@@ -104,10 +120,17 @@ public class AsyncDrawable extends Drawable {
}
// yeah
- public void setCallback2(@Nullable Callback callback) {
+ @SuppressWarnings("WeakerAccess")
+ public void setCallback2(@Nullable Callback cb) {
- this.callback = callback;
- super.setCallback(callback);
+ // @since 4.2.1-SNAPSHOT
+ // wrap callback so invalidation happens to this AsyncDrawable instance
+ // and not for wrapped result/placeholder
+ this.callback = cb == null
+ ? null
+ : new WrappedCallback(cb);
+
+ super.setCallback(cb);
// if not null -> means we are attached
if (callback != null) {
@@ -138,6 +161,7 @@ public class AsyncDrawable extends Drawable {
/**
* @since 3.0.1
*/
+ @SuppressWarnings("WeakerAccess")
protected void setPlaceholderResult(@NonNull Drawable placeholder) {
// okay, if placeholder has bounds -> use it, otherwise use original imageSize
@@ -175,7 +199,6 @@ public class AsyncDrawable extends Drawable {
}
this.result = result;
- this.result.setCallback(callback);
initBounds();
}
@@ -210,6 +233,12 @@ public class AsyncDrawable extends Drawable {
final Rect bounds = resolveBounds();
result.setBounds(bounds);
+ // @since 4.2.1-SNAPSHOT, we set callback after bounds are resolved
+ // to reduce number of invalidations
+ result.setCallback(callback);
+
+ // so, this method will check if there is previous bounds and call invalidate _BEFORE_
+ // applying new bounds. This is why it is important to have initial bounds empty.
setBounds(bounds);
invalidateSelf();
@@ -291,6 +320,7 @@ public class AsyncDrawable extends Drawable {
return imageSizeResolver.resolveImageSize(this);
}
+ @NonNull
@Override
public String toString() {
return "AsyncDrawable{" +
@@ -302,4 +332,30 @@ public class AsyncDrawable extends Drawable {
", waitingForDimensions=" + waitingForDimensions +
'}';
}
+
+ // @since 4.2.1-SNAPSHOT
+ // Wrapped callback to trigger invalidation for this AsyncDrawable instance (and not result/placeholder)
+ private class WrappedCallback implements Callback {
+
+ private final Callback callback;
+
+ WrappedCallback(@NonNull Callback callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void invalidateDrawable(@NonNull Drawable who) {
+ callback.invalidateDrawable(AsyncDrawable.this);
+ }
+
+ @Override
+ public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
+ callback.scheduleDrawable(AsyncDrawable.this, what, when);
+ }
+
+ @Override
+ public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
+ callback.unscheduleDrawable(AsyncDrawable.this, what);
+ }
+ }
}
diff --git a/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableSpan.java b/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableSpan.java
index 0d70b62a..7c979e23 100644
--- a/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableSpan.java
+++ b/markwon-core/src/main/java/io/noties/markwon/image/AsyncDrawableSpan.java
@@ -42,11 +42,9 @@ public class AsyncDrawableSpan extends ReplacementSpan {
this.alignment = alignment;
this.replacementTextIsLink = replacementTextIsLink;
- // additionally set intrinsic bounds if empty
- final Rect rect = drawable.getBounds();
- if (rect.isEmpty()) {
- drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
- }
+ // @since 4.2.1-SNAPSHOT we do not set intrinsic bounds
+ // at this point they will always be 0,0-1,1, but this
+ // will trigger another invalidation when we will have bounds
}
@Override