0

I am using an alpha interpolation on a custom CharacterStyle by setting an alpha value mAlpha and then updating the color in updateDrawState(TextPaint tp).

I'm running into an issue on newer Android devices, specifically devices running API 23 don't seem to render the Spans at all. On older devices the updates work properly.

Has anyone dealt with this issue?

Here is the code for the alpha being set inside onDraw in a custom EditText for some weird reason the characters sometimes do not show up on certain devices on other devices the animation works perfectly:

// If the view is animating (meaning we set the text) go ahead and draw the animations
    if (mIsAnimating) {

        long delta = AnimationUtils.currentAnimationTimeMillis() - mStart;

        // Initialize our word span
        FadeWordSpan[] words = mFadeText.getSpans(0, mFadeText.length(), FadeWordSpan.class);

        // Get our length
        final int length = words.length;

        // For each letter animate in the word
        for (int i = 0; i < length; i++) {

            // Get our word
            FadeWordSpan word = words[i];

            long value = (delta - (i * mDurationPerWord));

            // Calculate our delta
            float dx = (float) Math.max(Math.min(value, mDurationPerWord), 0);

            // Calculate the alpha based on the delta dx value
            float alpha = mInterpolator.getInterpolation(dx / (float) mDurationPerWord);

            // Set our interpolation alpha
            word.setAlpha(alpha);

        }

        boolean keepRedrawing = delta < mDurationPerWord * length;

        // If our delta is less than the duration per word times the length then we need to keep re-drawing
        if (keepRedrawing) {

            // Call redraw on animation change
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                postInvalidateOnAnimation();
            } else
                ViewCompat.postInvalidateOnAnimation(this);

        // Else let our listener know we are done animating
        } else {

            // Go ahead and set our characters styles
            FadeWordSpan[] letters = mFadeText.getSpans(0, mFadeText.length(), FadeWordSpan.class);

            for (FadeWordSpan word : letters) {
                mFadeText.removeSpan(word);
            }

            // Some animating
            mIsAnimating = false;

            // If our listener is not null go ahead and let the delegate know we have finished
            // animating in the text
            if (mAnimatingTextFinished != null) {
                mAnimatingTextFinished.onFinished();
                mAnimatingTextFinished = null;
            }
        }
    }

UPDATE:

Devices that work are:

  • Samsung S6
  • HTC Devices
  • Nexus 4

Devices that don't work are:

  • Samsung S3
  • Motorola Nexus 6
  • Nexus 5

Update 2:

After debugging, it seems to be that updateDrawState(TextPaint tp) never stops on the devices that don't work. Maybe it's blocking the part of the app that needs to render the text in.

Update 3:

StackTrace:

enter image description here

Update 4: Word Span Class

public class FadeWordSpan extends CharacterStyle implements UpdateAppearance {

    private float mAlpha = 0.0f;

    public FadeWordSpan() {
    }

    public void setAlpha(float alpha) {
        this.mAlpha = Math.max(Math.min(alpha, 1.0f), 0.0f);
    }

    public float getAlpha() {
        return mAlpha;
    }

    @Override
    public void updateDrawState(TextPaint tp) {

        // This constantly gets called on certain devices
        Log.i(TAG, "updateDrawState: ");

        int red = Color.red(Color.WHITE);
        int green = Color.green(Color.WHITE);
        int blue = Color.blue(Color.WHITE);
        int alpha = Color.alpha(Color.WHITE);

        int color = Color.argb((int) (alpha * mAlpha), red, green, blue);

        tp.setColor(color);
    }

}

Update 5:

Stack Dump (same as above, gets called infinitely):

W: java.lang.Throwable: stack dump
W:     at java.lang.Thread.dumpStack(Thread.java:490)
W:     at com.customapp.utils.views.text.FadeWordSpan.updateDrawState(FadeWordSpan.java:43)
W:     at android.text.TextLine.handleRun(TextLine.java:953)
W:     at android.text.TextLine.measureRun(TextLine.java:417)
W:     at android.text.TextLine.measure(TextLine.java:296)
W:     at android.text.TextLine.metrics(TextLine.java:270)
W:     at android.text.BoringLayout.isBoring(BoringLayout.java:311)
W:     at android.widget.TextView.onMeasure(TextView.java:6875)
W:     at android.view.View.measure(View.java:18794)
W:     at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
W:     at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
W:     at android.view.View.measure(View.java:18794)
W:     at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
W:     at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
W:     at android.view.View.measure(View.java:18794)
W:     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
W:     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
W:     at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
W:     at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
W:     at android.view.View.measure(View.java:18794)
W:     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
W:     at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
W:     at android.view.View.measure(View.java:18794)
W:     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
W:     at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
W:     at android.view.View.measure(View.java:18794)
W:     at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
W:     at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
W:     at android.view.View.measure(View.java:18794)
W:     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
W:     at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
W:     at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
W:     at android.view.View.measure(View.java:18794)
W:     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
W:     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
W:     at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
W:     at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
W:     at android.view.View.measure(View.java:18794)
W:     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
W:     at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
W:     at android.view.View.measure(View.java:18794)
W:     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
W:     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
W:     at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
W:     at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
W:     at android.view.View.measure(View.java:18794)
W:     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
W:     at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
W:     at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2643)
W:     at android.view.View.measure(View.java:18794)
W:     at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2100)
W:     at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1216)
W:     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1452)
W:     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
W:     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
W:     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
W:     at android.view.Choreographer.doCallbacks(Choreographer.java:670)
W:     at android.view.Choreographer.doFrame(Choreographer.java:606)
W:     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
W:     at android.os.Handler.handleCallback(Handler.java:739)
W:     at android.os.Handler.dispatchMessage(Handler.java:95)
W:     at android.os.Looper.loop(Looper.java:148)
W:     at android.app.ActivityThread.main(ActivityThread.java:5417)
W:     at java.lang.reflect.Method.invoke(Native Method)
W:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
W:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
AndyRoid
  • 5,062
  • 8
  • 38
  • 73
  • post your `FadeWordSpan` span class – pskink May 05 '16 at 05:49
  • Done it's posted up. – AndyRoid May 05 '16 at 05:55
  • Here's a link to a fuller set of code, I posted parts of it in another question: http://stackoverflow.com/questions/36953863/how-to-alpha-translate-animate-each-word-in-a-textview-instead-of-each-charact – AndyRoid May 05 '16 at 05:57
  • I've seen that blog before, I don't think it does anything since `updateDrawState(TextPaint tp)` will still get called. When a span is set and the view is invalidated it gets called infinitely on certain devices. – AndyRoid May 05 '16 at 06:09
  • Did all that before, onDraw stops getting called after the timer runs out but updateDrawState(TextPaint tp) keeps getting called infinitely from that stacktrace I posted above – AndyRoid May 05 '16 at 06:12
  • Might be a good idea? But running the debugger like above shows the trace as well, can try that now. – AndyRoid May 05 '16 at 06:14
  • Posted Stack dump above, it's the same as the debugger – AndyRoid May 05 '16 at 06:19
  • I get the same thing, when I extend `ForegroundColorSpan` and add a `super(color)` for the constructor. – AndyRoid May 05 '16 at 06:33
  • The logcat dump was the same stack trace! – AndyRoid May 05 '16 at 10:59
  • Ahhh I see the hyperlink now, didn't catch that before will test it! – AndyRoid May 05 '16 at 22:34

0 Answers0