【问题标题】:Xamarin: Unable to retrieve URLSpans from a TextView with linksXamarin:无法从带有链接的 TextView 中检索 URLSpan
【发布时间】:2018-01-12 14:00:25
【问题描述】:

我正在尝试从 Xamarin 项目中的 textView 中删除链接下划线。 以下 sn-p 在 java 项目中运行良好:

    textView.setText("You must agree to our terms and conditions");

    Pattern pattern1 = Pattern.compile("terms and conditions");
    Linkify.addLinks(textView, pattern1, "http://www.someLink.com", null, new Linkify.TransformFilter() {
        @Override
        public String transformUrl(Matcher match, String url) {
            return "";
        }
    });

    Spannable s = new SpannableString(textView.getText());
    URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class);
    for (URLSpan span: spans) {
        int start = s.getSpanStart(span);
        int end = s.getSpanEnd(span);
        NoUnderline noUnderline = new NoUnderline();
        s.setSpan(noUnderline, start, end, 0);
    }
    textView.setText(s);

现在,在 C# 中翻译完全相同的代码,我得出以下结论:

        TextView.Text = "You must agree to our terms and conditions";

        Java.Util.Regex.Pattern termsAndConditionsMatcher = Java.Util.Regex.Pattern.Compile("terms and conditions");
        Linkify.AddLinks(TextView, termsAndConditionsMatcher, "https://www.someLink.com/", null, new EmptyLinkTransformer());

        var spannable = new SpannableString(TextView.Text);
        var spans = spannable.GetSpans(0, spannable.Length(), Java.Lang.Class.FromType(typeof(URLSpan)));

        var urlSpans = new URLSpan[spans.Length];
        for (var i = 0; i < urlSpans.Length; i++)
        {
            urlSpans[i] = spans[i] as URLSpan;
        }

        foreach (URLSpan span in urlSpans)
        {
            int start = spannable.GetSpanStart(span);
            int end = spannable.GetSpanEnd(span);
            var updated = new NoUnderlineSpan();
            spannable.SetSpan(updated, start, end, 0);
        }

        TextView.TextFormatted = spannable;

问题是 spannable.GetSpans(0, spannable.Length(), Java.Lang.Class.FromType(typeof(URLSpan))) 返回 0 个元素,即使我看到了链接在 UI 上被着色和下划线。

Thisthis 的帖子表明我正确使用了该方法。我在这里做错了吗?

【问题讨论】:

    标签: c# android xamarin.android


    【解决方案1】:

    Xamarin:无法从带有链接的 TextView 中检索 URLSpans

    这里有一个解决方法:您可以使用ClickableSpan 而不是URLSpan 来实现相同的功能。

    自定义 ClickableSpan 类并覆盖 UpdateDrawState 以从超链接 TextView 中删除下划线:

    class MyClickableSpan : ClickableSpan
    {
        private MainActivity mainActivity;
    
        public MyClickableSpan(MainActivity mainActivity)
        {
            this.mainActivity = mainActivity;
        }
    
        public override void OnClick(View widget)
        {
            Intent browserIntent = new Intent(Intent.ActionView, Uri.Parse("http://www.somelink.com/"));
            mainActivity.StartActivity(browserIntent);
        }
    
        public override void UpdateDrawState(TextPaint ds)
        {
            base.UpdateDrawState(ds);
            ds.Color = Color.Red;
            ds.UnderlineText = false;
        }
    }
    

    使用时:

    TextView textview = FindViewById<TextView>(Resource.Id.Terms);
    
    //You need add this line
    textview.MovementMethod = LinkMovementMethod.Instance;
    
    //This is the Text of TextView
    SpannableString ss1 = new SpannableString("You must agree to our terms and conditions");
    
    //22 means start position, ss1.Length() means end position
    ss1.SetSpan(new MyClickableSpan(this), 22, ss1.Length(), SpanTypes.ExclusiveExclusive);
    
    //set text for your TextView
    textview.TextFormatted = ss1;
    

    【讨论】:

      【解决方案2】:

      您可以使用以下代码从 TextView 获取现有跨度

      TextView mytextview = ....;
      
      var spans = Android.Text.SpannableFactory.Instance.NewSpannable(mytextview.TextFormatted);
      
      foreach (URLSpan span in spans.GetSpans(0, mytextview.Text.Length, Java.Lang.Class.FromType(typeof(URLSpan))))
      {
          //Use an Android.Text.SpannableStringBuilder to build your new spannabletext
          var ssb = new Android.Text.SpannableStringBuilder();
          //Do your business here.
      }
      
      //Then set your text to your TextView
      mytextview.SetText(ssb, TextView.BufferType.Spannable);
      

      如果您想再次从 textview 中获取 span,只需再次执行相同的代码即可。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-11
        • 1970-01-01
        • 1970-01-01
        • 2019-09-29
        相关资源
        最近更新 更多