XamarinAndroid 中的 SpannableString

SpannableString in XamarinAndroid

我有一个 6 行的“文本视图”。 当我点击每一行时,我想用 Toast 显示每一行的编号。 当我使用“跨度”时,它只显示最后的行号。 如何为 Spans 写一个循环到 return 所有行号。 还有其他建议吗? 感谢您的帮助。

我的代码:

public class Activity1 : AppCompatActivity
{
    TextView textView;
    int count = 6; //Number of lines
    int next;
    string txt;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.activity_main);

        textView = FindViewById<TextView>(Resource.Id.textView1);
        txt = Resources.GetString(Resource.String.test);

        SpannableString ss = new SpannableString(txt);
        var clickableSpan = new MyClickableSpan();
        clickableSpan.Click += v => Toast.MakeText(this, "line : 1", ToastLength.Short).Show();
        ss.SetSpan(clickableSpan, 0, a, SpanTypes.ExclusiveExclusive);
        textView.TextFormatted = ss;
        textView.MovementMethod = new LinkMovementMethod();

        //For all lines
            //var clickableSpan1 = new MyClickableSpan();
            //var clickableSpan2 = new MyClickableSpan();
            //var clickableSpan3 = new MyClickableSpan();
            //var clickableSpan4 = new MyClickableSpan();
            //var clickableSpan5 = new MyClickableSpan();
       ...
    }
    private class MyClickableSpan : ClickableSpan
    {
        public Action<View> Click;

        public override void OnClick(View widget)
        {
            if (Click != null)
                Click(widget);
        }
        public override void UpdateDrawState(TextPaint textPaint)
        {
            textPaint.UnderlineText = false;
        }
    }
}

我的循环代码:

            for (int i = 0; i < ss.Length(); i = next)
            {
                // find the next span transition
                next = ss.NextSpanTransition(i, ss.Length(), Class.FromType(typeof(CharacterStyle)));
                // get all spans in this range
                int numOfSpans = 0;
                //CharacterStyle[] spans = ss.GetSpans(i, next, Class.FromType(typeof(CharacterStyle))); //return null!!!
                for (int j = 0; j < count; j++)
                {                        
                      numOfSpans++;
                }
                var clickableSpan = new MyClickableSpan();
                clickableSpan.Click += v => Toast.MakeText(this, "line : " + numOfSpans, ToastLength.Short).Show(); //return last number of lines : 6
                ss.SetSpan(clickableSpan, i, next, SpanTypes.ExclusiveExclusive);
                textView.TextFormatted = ss;
                textView.MovementMethod = new LinkMovementMethod();
            }

我不确定你想要实现什么,所以请更新你的描述:)

据我所知,错误在这里 textView.TextFormatted = ss; 当您设置等于 ss 时,它将在循环的每个步骤中覆盖文本视图的文本。

我给你写了一个代码,textview 有 6 个跨度,当你点击它们中的每一个时,它会显示跨度的数量。

public class MainActivity : AppCompatActivity
    {
        TextView textView;
        int count = 6; //Number of lines
        string txt;
        List<string> spans;
        int startIndex = 0;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.activity_main);

            textView = FindViewById<TextView>(Resource.Id.textView1);
            txt = Resources.GetString(Resource.String.test);

            //Split your txt on the number of spans - count??
            spans = new List<string>()
            {
                "Span 1" + System.Environment.NewLine,
                "Span 2" + System.Environment.NewLine,
                "Span 3" + System.Environment.NewLine,
                "Span 4" + System.Environment.NewLine,
                "Span 5" + System.Environment.NewLine,
                "Span 6" + System.Environment.NewLine
            };

            SpannableStringBuilder spannableString = new SpannableStringBuilder();

            for (int i = 0; i < count; i++)
            {
                ISpannable wordtoSpan = new SpannableString(spans[i]);

                var clickableSpan = new MyClickableSpan(ShowToastForSpan, i);

                spannableString.Append(spans[i], clickableSpan, SpanTypes.ExclusiveExclusive);
            }

            textView.TextFormatted = spannableString;

            textView.MovementMethod = LinkMovementMethod.Instance;
        }

        private void ShowToastForSpan(int spanNumber)
        {
            Toast.MakeText(this, $"Span number {spanNumber + 1} was clicked", ToastLength.Long).Show();
        }
    }

    class MyClickableSpan : ClickableSpan
    {
        private Action<int> _onSpanClicked;
        private int _spanNumber;
        Random rnd = new Random();

        public MyClickableSpan(Action<int> onSpanClicked, int spanNumber)
        {
            _onSpanClicked = onSpanClicked;
            _spanNumber = spanNumber;
        }

        public override void OnClick(View widget)
        {
            _onSpanClicked.Invoke(_spanNumber);
        }

        public override void UpdateDrawState(TextPaint textPaint)
        {
            textPaint.Color = Color.Argb(255, rnd.Next(256), rnd.Next(256), rnd.Next(256));
            textPaint.UnderlineText = false;
        }
    }