Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b985721 authored by Chet Haase's avatar Chet Haase
Browse files

Add equals() and hashcode() to SpannableString

ActionBar uses a transition to animate text changes. This transition
depends on testing the equality of start/end text values in CharSequence
objects. Without equals(), SpannableString will return false for objects
whose references are different, but whose text is exactly the same.

This CL adds the equals() method, and the accompanying hashcode method,
to ensure that two Spanned implementations will always be equal
if their text and span data are equal.

Issue #10760075 Wrong unread count in actionbar

Change-Id: I5e77d40dd302eca035e8c56d40f3cd0aef8e6424
parent a2d65108
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
@@ -1288,6 +1288,47 @@ public class SpannableStringBuilder implements CharSequence, GetChars, Spannable
        return mFilters;
    }

    // Same as SpannableStringInternal
    @Override
    public boolean equals(Object o) {
        if (o instanceof Spanned &&
                toString().equals(o.toString())) {
            // Check span data
            Object[] otherSpans = ((Spanned) o).getSpans(0,
                    ((Spanned) o).length(), Object.class);
            if (mSpanCount == otherSpans.length) {
                for (int i = 0; i < mSpanCount; ++i) {
                    Object thisSpan = mSpans[i];
                    Object otherSpan = otherSpans[i];
                    if (!thisSpan.equals(otherSpan) ||
                            getSpanStart(thisSpan) != getSpanStart(otherSpan) ||
                            getSpanEnd(thisSpan) != getSpanEnd(otherSpan) ||
                            getSpanFlags(thisSpan) != getSpanFlags(otherSpan)) {
                        return false;
                    }
                }
                return true;
            }

        }
        return false;
    }

    // Same as SpannableStringInternal
    @Override
    public int hashCode() {
        int hash = toString().hashCode();
        hash = hash * 31 + mSpanCount;
        for (int i = 0; i < mSpanCount; ++i) {
            Object span = mSpans[i];
            hash = hash * 31 + span.hashCode();
            hash = hash * 31 + getSpanStart(span);
            hash = hash * 31 + getSpanEnd(span);
            hash = hash * 31 + getSpanFlags(span);
        }
        return hash;
    }

    private static final InputFilter[] NO_FILTERS = new InputFilter[0];
    private InputFilter[] mFilters = NO_FILTERS;

+41 −0
Original line number Diff line number Diff line
@@ -358,6 +358,47 @@ import java.lang.reflect.Array;
        }
    }

    // Same as SpannableStringBuilder
    @Override
    public boolean equals(Object o) {
        if (o instanceof Spanned &&
                toString().equals(o.toString())) {
            // Check span data
            Object[] otherSpans = ((Spanned) o).getSpans(0,
                    ((Spanned) o).length(), Object.class);
            if (mSpanCount == otherSpans.length) {
                for (int i = 0; i < mSpanCount; ++i) {
                    Object thisSpan = mSpans[i];
                    Object otherSpan = otherSpans[i];
                    if (!thisSpan.equals(otherSpan) ||
                            getSpanStart(thisSpan) != getSpanStart(otherSpan) ||
                            getSpanEnd(thisSpan) != getSpanEnd(otherSpan) ||
                            getSpanFlags(thisSpan) != getSpanFlags(otherSpan)) {
                        return false;
                    }
                }
                return true;
            }

        }
        return false;
    }

    // Same as SpannableStringBuilder
    @Override
    public int hashCode() {
        int hash = toString().hashCode();
        hash = hash * 31 + mSpanCount;
        for (int i = 0; i < mSpanCount; ++i) {
            Object span = mSpans[i];
            hash = hash * 31 + span.hashCode();
            hash = hash * 31 + getSpanStart(span);
            hash = hash * 31 + getSpanEnd(span);
            hash = hash * 31 + getSpanFlags(span);
        }
        return hash;
    }

    private String mText;
    private Object[] mSpans;
    private int[] mSpanData;
+7 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.graphics.Color;
import android.util.Log;
import android.view.ViewGroup;
import android.widget.TextView;

@@ -36,6 +37,9 @@ import java.util.Map;
 * @hide
 */
public class TextChange extends Transition {

    private static final String LOG_TAG = "TextChange";

    private static final String PROPNAME_TEXT = "android:textchange:text";
    private static final String PROPNAME_TEXT_COLOR = "android:textchange:textColor";

@@ -224,6 +228,9 @@ public class TextChange extends Transition {
                }
            };
            addListener(transitionListener);
            if (DBG) {
                Log.d(LOG_TAG, "createAnimator returning " + anim);
            }
            return anim;
        }
        return null;