I have written a custom span for SpannableStrings
"ImageURLSpan
" that extends ImageSpan
.
- The ImageSpan is configured with a Drawable "
RemoteImageDrawable
" that renders a static placeholder, loads an image from the internet, then when the image has finished loading, it should render the loaded bitmap instead of the placeholder. That would happen if thedraw()
method of the drawable is called again (by the parentview
?)
My problem is, at the drawable level, I don't know how to trigger an 'auto-refresh' at any point in the future (once the image is loaded). I have tried to call the parent view's invalidate
with non-consistent results: Sometimes the draw method of the drawable is called again -so it's properly refreshed- and sometimes it's not. It's totally random!
What's the correct approach for a drawable that changes its content to "invalidate" itself? shouldn't the invalidation of the parent View cause all child drawables to invalidate? Do I need to use the Drawable callbacks or are they not related to my problem?
Please find attached relevant code:
public class ImageUrlSpan extends ImageSpan {
public ImageUrlSpan(final View parentView, String imageUrl, int width, int height) {
super(
new RemoteImageDrawable(
parentView, imageUrl, width, height, new ImageLoaders.OnDrawableDownloadListener() {
@Override
public void onDrawableLoaded(Drawable bitmap) {
parentView.invalidate();
// this works sometimes
if (Conf.LOG_ON) Log.v(TAG, "Invalidating parent view... will that refresh myself? "+parentView);
}
}
));
}
}
About the code of RemoteImageDrawable
, you only have to know
it's a simple drawable that just paints a placeholder, schedules a image load, then when the image is ready, calls the listener above.
Whenever its
draw
method is called again (supposedly as a consequence of the invalidate in the listener above), the loaded bitmap would be rendered instead of the placeholder.I omit the source code for simplicity, the problem is as simple as the draw method not being called most of the times. It puzzles me that sometimes it's called !
The following stack trace depicts the callstack of the first call to the Drawable's DRAW. You can see it comes from View.draw() -> StaticLayout.draw() -> RemoteImageDrawable.draw().
W/System.err(26142): at com.regaliz.custom.RemoteImageDrawable.draw(RemoteImageDrawable.java:71)
W/System.err(26142): at android.text.style.DynamicDrawableSpan.draw(DynamicDrawableSpan.java:107)
W/System.err(26142): at android.text.TextLine.handleReplacement(TextLine.java:854)
W/System.err(26142): at android.text.TextLine.handleRun(TextLine.java:937)
W/System.err(26142): at android.text.TextLine.drawRun(TextLine.java:395)
W/System.err(26142): at android.text.TextLine.draw(TextLine.java:193)
W/System.err(26142): at android.text.Layout.drawText(Layout.java:348)
W/System.err(26142): at android.text.Layout.draw(Layout.java:205)
W/System.err(26142): at android.text.Layout.draw(Layout.java:183)
W/System.err(26142): at com.regaliz.gui.views.SimpleTextView.drawTextLayout(SimpleTextView.java:347)
W/System.err(26142): at com.regaliz.gui.views.SimpleTextView.onDraw(SimpleTextView.java:310)
W/System.err(26142): at com.regaliz.gui.views.helper.SimpleTextViewMarquee.onDraw(SimpleTextViewMarquee.java:114)
W/System.err(26142): at android.view.View.draw(View.java:13877)
W/System.err(26142): at android.view.View.getDisplayList(View.java:12815)
W/System.err(26142): at android.view.View.getDisplayList(View.java:12859)
W/System.err(26142): at android.view.View.draw(View.java:13593)
W/System.err(26142): at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
W/System.err(26142): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
However, when I issue an invalidate, the drawable draw() is not called, so somewhere along this path, the view decides everything's already drawn :(
V/RemoteImageDrawable(26142): *** Remote bitmap loaded com.regaliz.util.AssetLoader$MeasuredBitmapDrawable@41d60798
V/ImageURLSpan(26142): Invalidating parent view after loaded... will it work? com.regaliz.gui.views.helper.SimpleTextViewMarquee{41f6c898 GFED..CL ........ 0,0-719,663}
V/ImageURLSpan(26142): Invalidating parent view end.