7

如何检查两个 Spanned 对象是否相等(它们应用了相同的内容和跨度)?我宁愿不实现该equals(Spanned span)方法。:)

4

1 回答 1

4

equalsAndroid中的 span 类缺少hashCode方法。我不知道为什么。也许这只是一个疏忽?该方法也有一个错误SpannableStringBuilder.equals()

解决方法正是您所担心的。如果你使用,例如,AbsoluteSizeSpan你需要扩展它并添加equalshashCode方法。将跨度添加到时使用您的版本而不是框架的版本SpannableStringBuilder

import android.os.Parcel;


public class AbsoluteSizeSpan extends android.text.style.AbsoluteSizeSpan {


    public AbsoluteSizeSpan(int size) {
        super(size);
    }

    public AbsoluteSizeSpan(int size, boolean dip) {
        super(size, dip);
    }

    public AbsoluteSizeSpan(Parcel src) {
        super(src);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        AbsoluteSizeSpan that = (AbsoluteSizeSpan) o;

        if (getSize() != that.getSize()) return false;
        return getDip() == that.getDip();
    }

    @Override
    public int hashCode() {
        int result = getSize();
        result = 31 * result + (getDip() ? 1 : 0);
        return result;
    }
}

在 Android 框架的SpannableStringBuilder.equals()方法中,已排序的 span 列表与未排序的 span 列表相比。要解决此问题,请覆盖SpannableStringBuilder.equals()

public class SpannableStringBuilder extends android.text.SpannableStringBuilder {

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

将跨度类的覆盖版本添加到您的SpannableStringBuilder.

于 2017-09-25T10:51:57.357 回答