如何在Android中使用SpanWatcher?

时间:2012-05-25 13:49:50

标签: android xamarin.android

我一直试图找到一个android issue with zero length formatting Spans的工作。我想,好吧,我只会删除长度为零的Spans。经过一番环顾,我认为SpanWatcher是一个很好的方法。但是,似乎缺乏关于如何实现或添加SpanWatchers的示例。

我在MonoDroid中试过这个:

public class PreventZeroLenSpan : Java.Lang.Object, ISpanWatcher
{
    void ISpanWatcher.OnSpanAdded (ISpannable text, Java.Lang.Object what, int start, int end)
    {
        if (what==this) return;
        var CS = what as Android.Text.Style.CharacterStyle;
        if (CS==null) return;
        if (start==end) text.RemoveSpan(CS);
    }

    void ISpanWatcher.OnSpanChanged (ISpannable text, Java.Lang.Object what, int ostart, int oend, int nstart, int nend)
    {
        if (what==this) return;
        var CS = what as Android.Text.Style.CharacterStyle;
        if (CS==null) return;
        if (nstart==nend) text.RemoveSpan(CS);
    }

    void ISpanWatcher.OnSpanRemoved (ISpannable text, Java.Lang.Object what, int start, int end)
    {
        // nothing
    }
}

如果我在事先将其添加到SpannableStringBuilder或SpannableString之前调用事件,但在进入EditText控件后它不再响应。

        var Str = new SpannableStringBuilder("Test IT");
        var Sty = new ForegroundColorSpan(Android.Graphics.Color.Blue);
        Str.SetSpan(SpanWatch,0,Str.Length(), SpanTypes.InclusiveInclusive);
        Str.SetSpan(Sty,5,7, SpanTypes.InclusiveInclusive);
        txEdit.SetText(Str, TextView.BufferType.Editable);

SpanWatcher实现NoCopySpan,因此不会将其复制到EditText中。我找不到任何方法将SpanWatcher直接添加到EditText(有一种添加TextWatcher的方法)。

我想如果我无法弄清楚SpanWatcher,我可以在每次文本更改时扫描整个内容的零长度跨度。这似乎效率低下。 (我可能需要稍后为我的图形换行指示删除事件。)

欢迎提出任何想法,欢迎使用Java或MonoDroid中的示例。

修改

我仍然有兴趣知道如何使用SpanWatcher(看起来效率更高),但对于其他任何努力消除零长度跨度的人,你可以使用以下TextWatcher执行EditText.AddTextChangedListener():

public class PreventZeroLenSpanWatcher : Java.Lang.Object, ITextWatcher
{
    void ITextWatcher.AfterTextChanged (IEditable s)
    {
        var Objs = s.GetSpans(0,s.Length(), Java.Lang.Class.FromType(typeof(Android.Text.Style.CharacterStyle)));
        foreach (Android.Text.Style.CharacterStyle CS in Objs)
        {
            int Start = s.GetSpanStart(CS);
            int End = s.GetSpanEnd(CS);
            if (Start == End) s.RemoveSpan(CS);
        }
    }

    void ITextWatcher.BeforeTextChanged (Java.Lang.ICharSequence s, int start, int count, int after)
    {
        // nothing
    }

    void ITextWatcher.OnTextChanged (Java.Lang.ICharSequence s, int start, int before, int count)
    {
        // nothing
    }
}

EDIT2

如果你这样做,你至少可以将SpanWatcher放入EditText,但是一旦用户编辑了文本,你似乎再次松开它。必须有一些由控件在内部进行的复制,并且SpanWatcher不可复制。

        IEditable txEditFormatted = ((IEditable)txEdit.TextFormatted);
        txEditFormatted.SetSpan(SpanWatch,0,txEditFormatted.Length(), SpanTypes.InclusiveInclusive);

我还尝试使用TextWatcher重新添加SpanWatcher,但到那时跨度已经改变了。

0 个答案:

没有答案