我一直试图找到一个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,但到那时跨度已经改变了。