在TextView中动态加载AnimationDrawable

T.S*_*.S. 8 animation android drawable

我需要用图像替换文本中的短语,然后将其附加到TextView.对于常规Drawables,这没有问题,但是当Drawable是AnimationDrawable时,我不知道在何时何地调用.start();.

这是我将文本追加到TextView的方法:

textview.append(Html.fromHtml(textWithHtmlImgTags, imagegetter, null));
Run Code Online (Sandbox Code Playgroud)

使用imagegetter替换textWithHtmlImgTags中的图像标记:

new ImageGetter()
{
    @Override
    public Drawable getDrawable(String source) {

        if(source.endsWith("_ani"))
        {
            Log.i("cmv", "This is an animated drawable.");

            AnimationDrawable dra = (AnimationDrawable)res.getDrawable(sRes.get(source));
            dra.setBounds(0, 0, dra.getIntrinsicWidth(), dra.getIntrinsicHeight());
            dra.start(); // This doesn't work..

            return dra;
        }

        Drawable dr = res.getDrawable(sRes.get(source));
        dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
        return dr;
    }

};
Run Code Online (Sandbox Code Playgroud)

添加了我的AnimationDrawables,但它们没有动画(它们被卡在第1帧上).

在文档中它说:

重要的是要注意,在Activity的onCreate()方法中,无法调用在AnimationDrawable上调用的start()方法,因为AnimationDrawable尚未完全附加到窗口.如果您想立即播放动画而不需要交互,那么您可能希望从Activity中的onWindowFocusChanged()方法调用它,当Android将窗口置于焦点时将调用它.

由于图像是动态添加的,我认为它与onCreate()没有任何关系.所以我想我可以.start()在我的抽签时给我打电话is not yet fully attached to the window,但我应该在何处/何时/怎么称呼它?

提前致谢!

shi*_*ami 6

我出来了解决方案.在自定义TextView中:

(1)首先,你必须决定动画开始和结束的时间.

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();

    handleAnimationDrawable(true);
}

@Override
protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();

    handleAnimationDrawable(false);
}

private void handleAnimationDrawable(boolean isPlay) {
    CharSequence text = getText();
    if (text instanceof Spanned) {
        Spanned span = (Spanned) text;
        ImageSpan[] spans = span.getSpans(0, span.length() - 1,
                ImageSpan.class);
        for (ImageSpan s : spans) {
            Drawable d = s.getDrawable();
            if (d instanceof AnimationDrawable) {
                AnimationDrawable animationDrawable = (AnimationDrawable) d;
                if (isPlay) {
                    animationDrawable.setCallback(this);
                    animationDrawable.start();
                } else {
                    animationDrawable.stop();
                    animationDrawable.setCallback(null);
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

(2)然后实现自己的Drawable.Callback来触发重绘.

@Override
public void invalidateDrawable(Drawable dr) {
    invalidate();
}

@Override
public void scheduleDrawable(Drawable who, Runnable what, long when) {
    if (who != null && what != null) {
        mHandler.postAtTime(what, when);
    }
}

@Override
public void unscheduleDrawable(Drawable who, Runnable what) {
    if (who != null && what != null) {
        mHandler.removeCallbacks(what);
    }
}
Run Code Online (Sandbox Code Playgroud)