AsyncDrawable defer invalidation

This commit is contained in:
Dimitry Ivanov 2019-08-01 12:44:26 +03:00
parent 2a43797023
commit b6fa66914f
2 changed files with 42 additions and 4 deletions

View File

@ -7,6 +7,7 @@
* Add `requirePlugin(Class)` and `getPlugins` for `Markwon` instance
* TablePlugin -> defer table invalidation (via `View.post`), so only one invalidation
happens with each draw-call
* AsyncDrawableSpan -> defer invalidation
# 4.0.2
* Fix `JLatexMathPlugin` formula placeholder (cannot have line breaks) ([#149])

View File

@ -57,11 +57,14 @@ public abstract class AsyncDrawableScheduler {
textView.setTag(R.id.markwon_drawables_scheduler, listener);
}
// @since 4.1.0-SNAPSHOT
final DrawableCallbackImpl.Invalidator invalidator = new TextViewInvalidator(textView);
AsyncDrawable drawable;
for (AsyncDrawableSpan span : spans) {
drawable = span.getDrawable();
drawable.setCallback2(new DrawableCallbackImpl(textView, drawable.getBounds()));
drawable.setCallback2(new DrawableCallbackImpl(textView, invalidator, drawable.getBounds()));
}
}
}
@ -109,11 +112,23 @@ public abstract class AsyncDrawableScheduler {
private static class DrawableCallbackImpl implements Drawable.Callback {
// @since 4.1.0-SNAPSHOT
// interface to be used when bounds change and view must be invalidated
interface Invalidator {
void invalidate();
}
private final TextView view;
private final Invalidator invalidator; // @since 4.1.0-SNAPSHOT
private Rect previousBounds;
DrawableCallbackImpl(TextView view, Rect initialBounds) {
DrawableCallbackImpl(
@NonNull TextView view,
@NonNull Invalidator invalidator,
Rect initialBounds) {
this.view = view;
this.invalidator = invalidator;
this.previousBounds = new Rect(initialBounds);
}
@ -136,8 +151,10 @@ public abstract class AsyncDrawableScheduler {
// but if the size has changed, then we need to update the whole layout...
if (!previousBounds.equals(rect)) {
// the only method that seems to work when bounds have changed
view.setText(view.getText());
// @since 4.1.0-SNAPSHOT
// invalidation moved to upper level (so invalidation can be deferred,
// and multiple calls combined)
invalidator.invalidate();
previousBounds = new Rect(rect);
} else {
@ -156,4 +173,24 @@ public abstract class AsyncDrawableScheduler {
view.removeCallbacks(what);
}
}
private static class TextViewInvalidator implements DrawableCallbackImpl.Invalidator, Runnable {
private final TextView textView;
TextViewInvalidator(@NonNull TextView textView) {
this.textView = textView;
}
@Override
public void invalidate() {
textView.removeCallbacks(this);
textView.post(this);
}
@Override
public void run() {
textView.setText(textView.getText());
}
}
}