【问题标题】:Android ClickableSpan get text onClick()Android ClickableSpan 获取文本 onClick()
【发布时间】:2013-11-14 01:15:44
【问题描述】:

我正在 TextView 中处理 ClickableSpan,我正在尝试获取单击的 span 的文本。这是我的代码。

// this is the text we'll be operating on
SpannableString text = new SpannableString("Lorem ipsum dolor sit amet");

// make "dolor" (characters 12 to 17) display a toast message when touched
ClickableSpan clickableSpan = new ClickableSpan() {
    @Override
    public void onClick(View view) {
        // This will get "Lorem ipsum dolor sit amet", but I just want "dolor"
        String text = ((TextView) view).getText().toString(); 
        Toast.makeText(context, text, Toast.LENGTH_LONG).show();
    }
};

text.setSpan(clickableSpan, 12, 17, 0);

如您所见,我将clickablespan 设置为TextView 从字符12 到17,我想在onClick 事件中获取这些字符。

反正我能做到吗?或者至少我可以将12, 17 参数传递给onClick 事件吗?

谢谢!

【问题讨论】:

    标签: android onclick textview clickable


    【解决方案1】:

    试试这个:

    public class LoremIpsumSpan extends ClickableSpan {
        @Override
        public void onClick(View widget) {
            // TODO add check if widget instanceof TextView
            TextView tv = (TextView) widget;
            // TODO add check if tv.getText() instanceof Spanned
            Spanned s = (Spanned) tv.getText();
            int start = s.getSpanStart(this);
            int end = s.getSpanEnd(this);
            Log.d(TAG, "onClick [" + s.subSequence(start, end) + "]");
        }
    }
    

    【讨论】:

    • 当然,确实...添加中提到的检查。// TODOs
    • 甚至适用于多个可点击的单词 :) 谢谢!但为什么它会起作用?所以 OnClick 接收到的视图是 textview,然后执行 tv.getText 会返回单击的 Spanned 对象,即使还有其他 Spannable 单词。这是如何工作的? @pskink
    • @fersarr tv.getText() 是一个 Spanned 对象,Spanned 对象可以有多个 span 而不是 Spannables
    【解决方案2】:

    稍微简单一点,如果需要也可以传递模型引用。

    public class SpecialClickableSpan extends ClickableSpan {
    
        String text;
    
        public SpecialClickableSpan(String text){
             super();
             this.text = text;
        }
    
        @Override
        public void onClick(View widget) {
             Log.d(TAG, "onClick [" + text + "]");
        }
    }
    

    然后调用 new SpecialClickableSpan("My Text")

    【讨论】:

      【解决方案3】:

      已编辑:之前的代码有误,这可行

          // make "dolor" (characters 12 to 17) display a toast message when touched
          ClickableSpan clickableSpan = new ClickableSpan() {
              @Override
              public void onClick(View view) {
                  TextView textView = (TextView) view;
                  CharSequence charSequence = textView.getText();
                  if (charSequence instanceof Spannable) {
                      Spannable spannableText = (Spannable)charSequence;
                      ClickableSpan[] spans = spannableText.getSpans(0, textView.length(), ClickableSpan.class);
                      for (ClickableSpan span : spans) {
                          int start = spannableText.getSpanStart(span);
                          int end = spannableText.getSpanEnd(span);
                          Toast.makeText(MainActivity.this, charSequence.subSequence(start, end), Toast.LENGTH_LONG).show();
                      }
                  }
              }
          };
      

      【讨论】:

      • 你确定吗?我还没有运行你的代码,但它似乎不起作用......你的sannableText 没有被使用,spanStr 尚未定义。顺便说一句,textView.getText() 返回的是 CharSequence,而不是 SpannableStringBuilder... 请您再检查一下吗?
      • 我的意思是 spannableText 而不是 spanStr。我是从头开始做的,我现在正在做一个真正的代码,并在一段时间内更新。
      • 我也在考虑 SpannedText,而不是 SpannableStringBuilder。无论如何,你是对的,这是行不通的。 getSpans 用于可编辑(EditText,而不是 TextView)
      【解决方案4】:

      你也可以像这样使用使字符串可跨越

      String htmlLinkText = "Lorem ipsum <a href='http://www.google.com'>dolor</a> sit amet";
          testView.setText(Html.fromHtml(htmlLinkText));
          testView.setMovementMethod(LinkMovementMethod.getInstance());
      
          CharSequence text = testView.getText();
          if (text instanceof Spannable) {
              int end = text.length();
              Spannable sp = (Spannable) testView.getText();
              URLSpan[] urls = sp.getSpans(0, end, URLSpan.class);
              SpannableStringBuilder style = new SpannableStringBuilder(text);
              style.clearSpans();//should clear old spans
              for (URLSpan url : urls) {
                  CustomerTextClick click = new CustomerTextClick(url.getURL());
                  style.setSpan(click, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
              }
              testView.setText(style);
          }
      

      CustomerTextClick 将是

      私有静态类 CustomerTextClick 扩展 ClickableSpan {

          private String mUrl;
      
          CustomerTextClick(String url) {
              mUrl = url;
          }
      
          @Override
          public void onClick(View widget) {
              // TODO Auto-generated method stub
              //Toast.makeText(ctx, "hello google!",Toast.LENGTH_LONG).show();
              // Do your action here
          }
      }
      

      经过测试和工作的代码。

      【讨论】:

      • 你也可以直接在for循环中使用点击监听为for (URLSpan url : urls) { CustomerTextClick click = new CustomerTextClick(url.getURL()); style.setSpan(new ClickableSpan() { @Override public void onClick(View widget) { } }, sp.getSpanStart(url), sp.getSpanEnd(url), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); }
      猜你喜欢
      • 2012-01-28
      • 2016-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多