Reduce number of invalidations in AsyncDrawable
This commit is contained in:
parent
2e7d0aa46b
commit
b55b1f0dcc
@ -4,6 +4,8 @@
|
|||||||
* Fix SpannableBuilder `subSequence` method
|
* Fix SpannableBuilder `subSequence` method
|
||||||
* Introduce Nougat check in `BulletListItemSpan` to position bullet (for bullets to be
|
* Introduce Nougat check in `BulletListItemSpan` to position bullet (for bullets to be
|
||||||
positioned correctly when nested inside other `LeadingMarginSpan`s)
|
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
|
# 4.2.0
|
||||||
* `MarkwonEditor` to highlight markdown input whilst editing (new module: `markwon-editor`)
|
* `MarkwonEditor` to highlight markdown input whilst editing (new module: `markwon-editor`)
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package="io.noties.markwon.app">
|
package="io.noties.markwon.app">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_ALL_DOWNLOADS" />
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".App"
|
android:name=".App"
|
||||||
|
@ -25,6 +25,7 @@ import io.noties.markwon.ext.tasklist.TaskListPlugin;
|
|||||||
import io.noties.markwon.html.HtmlPlugin;
|
import io.noties.markwon.html.HtmlPlugin;
|
||||||
import io.noties.markwon.image.ImagesPlugin;
|
import io.noties.markwon.image.ImagesPlugin;
|
||||||
import io.noties.markwon.image.file.FileSchemeHandler;
|
import io.noties.markwon.image.file.FileSchemeHandler;
|
||||||
|
import io.noties.markwon.image.gif.GifMediaDecoder;
|
||||||
import io.noties.markwon.image.network.OkHttpNetworkSchemeHandler;
|
import io.noties.markwon.image.network.OkHttpNetworkSchemeHandler;
|
||||||
import io.noties.markwon.syntax.Prism4jTheme;
|
import io.noties.markwon.syntax.Prism4jTheme;
|
||||||
import io.noties.markwon.syntax.Prism4jThemeDarkula;
|
import io.noties.markwon.syntax.Prism4jThemeDarkula;
|
||||||
@ -105,7 +106,8 @@ public class MarkdownRenderer {
|
|||||||
// default-media-decoder is also added automatically
|
// default-media-decoder is also added automatically
|
||||||
plugin
|
plugin
|
||||||
.addSchemeHandler(OkHttpNetworkSchemeHandler.create())
|
.addSchemeHandler(OkHttpNetworkSchemeHandler.create())
|
||||||
.addSchemeHandler(FileSchemeHandler.createWithAssets(context.getAssets()));
|
.addSchemeHandler(FileSchemeHandler.createWithAssets(context.getAssets()))
|
||||||
|
.addMediaDecoder(GifMediaDecoder.create(false));
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.usePlugin(SyntaxHighlightPlugin.create(prism4j, prism4jTheme))
|
.usePlugin(SyntaxHighlightPlugin.create(prism4j, prism4jTheme))
|
||||||
|
@ -55,6 +55,7 @@ public class AsyncDrawable extends Drawable {
|
|||||||
/**
|
/**
|
||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
@Nullable
|
@Nullable
|
||||||
public ImageSize getImageSize() {
|
public ImageSize getImageSize() {
|
||||||
return imageSize;
|
return imageSize;
|
||||||
@ -63,20 +64,33 @@ public class AsyncDrawable extends Drawable {
|
|||||||
/**
|
/**
|
||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
@NonNull
|
@NonNull
|
||||||
public ImageSizeResolver getImageSizeResolver() {
|
public ImageSizeResolver getImageSizeResolver() {
|
||||||
return imageSizeResolver;
|
return imageSizeResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @see #hasKnownDimensions()
|
||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
|
* @deprecated 4.2.1-SNAPSHOT
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||||
|
@Deprecated
|
||||||
public boolean hasKnownDimentions() {
|
public boolean hasKnownDimentions() {
|
||||||
return canvasWidth > 0;
|
return canvasWidth > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see #hasKnownDimentions()
|
* @since 4.2.1-SNAPSHOT
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||||
|
public boolean hasKnownDimensions() {
|
||||||
|
return canvasWidth > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #hasKnownDimensions()
|
||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
public int getLastKnownCanvasWidth() {
|
public int getLastKnownCanvasWidth() {
|
||||||
@ -84,9 +98,10 @@ public class AsyncDrawable extends Drawable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see #hasKnownDimentions()
|
* @see #hasKnownDimensions()
|
||||||
* @since 4.0.0
|
* @since 4.0.0
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
public float getLastKnowTextSize() {
|
public float getLastKnowTextSize() {
|
||||||
return textSize;
|
return textSize;
|
||||||
}
|
}
|
||||||
@ -95,6 +110,7 @@ public class AsyncDrawable extends Drawable {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
public boolean hasResult() {
|
public boolean hasResult() {
|
||||||
return result != null;
|
return result != null;
|
||||||
}
|
}
|
||||||
@ -104,10 +120,17 @@ public class AsyncDrawable extends Drawable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// yeah
|
// yeah
|
||||||
public void setCallback2(@Nullable Callback callback) {
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public void setCallback2(@Nullable Callback cb) {
|
||||||
|
|
||||||
this.callback = callback;
|
// @since 4.2.1-SNAPSHOT
|
||||||
super.setCallback(callback);
|
// 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 not null -> means we are attached
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
@ -138,6 +161,7 @@ public class AsyncDrawable extends Drawable {
|
|||||||
/**
|
/**
|
||||||
* @since 3.0.1
|
* @since 3.0.1
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
protected void setPlaceholderResult(@NonNull Drawable placeholder) {
|
protected void setPlaceholderResult(@NonNull Drawable placeholder) {
|
||||||
// okay, if placeholder has bounds -> use it, otherwise use original imageSize
|
// 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 = result;
|
||||||
this.result.setCallback(callback);
|
|
||||||
|
|
||||||
initBounds();
|
initBounds();
|
||||||
}
|
}
|
||||||
@ -210,6 +233,12 @@ public class AsyncDrawable extends Drawable {
|
|||||||
|
|
||||||
final Rect bounds = resolveBounds();
|
final Rect bounds = resolveBounds();
|
||||||
result.setBounds(bounds);
|
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);
|
setBounds(bounds);
|
||||||
|
|
||||||
invalidateSelf();
|
invalidateSelf();
|
||||||
@ -291,6 +320,7 @@ public class AsyncDrawable extends Drawable {
|
|||||||
return imageSizeResolver.resolveImageSize(this);
|
return imageSizeResolver.resolveImageSize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "AsyncDrawable{" +
|
return "AsyncDrawable{" +
|
||||||
@ -302,4 +332,30 @@ public class AsyncDrawable extends Drawable {
|
|||||||
", waitingForDimensions=" + waitingForDimensions +
|
", 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,11 +42,9 @@ public class AsyncDrawableSpan extends ReplacementSpan {
|
|||||||
this.alignment = alignment;
|
this.alignment = alignment;
|
||||||
this.replacementTextIsLink = replacementTextIsLink;
|
this.replacementTextIsLink = replacementTextIsLink;
|
||||||
|
|
||||||
// additionally set intrinsic bounds if empty
|
// @since 4.2.1-SNAPSHOT we do not set intrinsic bounds
|
||||||
final Rect rect = drawable.getBounds();
|
// at this point they will always be 0,0-1,1, but this
|
||||||
if (rect.isEmpty()) {
|
// will trigger another invalidation when we will have bounds
|
||||||
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user