【问题标题】:Handling Multiple ClickableSpan in a TextView在 TextView 中处理多个 ClickableSpan
【发布时间】:2015-02-18 07:09:40
【问题描述】:

我已经被这个问题困扰很久了。我所拥有的是一个简单的字符串"This is a link and this is another link"。我想让两个“链接”词都可以点击,在浏览器中打开不同的 URL。

  • 我能做的最简单的方法是在两个“链接”上设置 Click-able Span 具有不同 URL 的单词,但我面临的问题是找到 跨度的开始和结束位置。文字是动态的,我有 以编程方式查找位置。
  • 一种方法是查找单词的第一次出现 'link',找到开始和结束位置并设置跨度,然后 第二次出现。但这并不可靠。文本可能包含 不止一种重复词,如"This is a cat link and this is another cat link"。在这里,我必须链接“猫”和“链接” 通过 Click-able Span 具有不同 URL 的单词。我该怎么做?

【问题讨论】:

    标签: android textview


    【解决方案1】:

    这样试试

    String s="Cat link 1 Cat link 2 Cat link 3";
        SpannableString ss = new SpannableString(s);
        String first ="Cat link 1";
        String second ="Cat link 2";
        String third ="Cat link 3";
        int firstIndex = s.toString().indexOf(first);
        int secondIndex = s.toString().indexOf(second);
        ClickableSpan firstwordClick = new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                ///............
            }
        }; 
        ClickableSpan secondwordClick = new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                ///............
            }
        }; 
        ss.setSpan(firstwordClick,firstIndex, firstIndex+first.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        ss.setSpan(secondwordClick,secondIndex, secondIndex+second.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        textView.setLinksClickable(true);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
        textView.setText(ss,BufferType.SPANNABLE);
    

    【讨论】:

    • 请对这个做同样的事情,String s="first second third first second third"。该字符串可能包含多个我必须链接的重复单词。谢谢!
    • 这个你也可以自己做,也可以从你的角度加一些努力。如果遇到困难,请告诉我
    • 正如我所说,文本是动态的。它可能包含不止一种重复的单词。我面临的问题是找到我必须与不同链接链接的重复单词的开始和结束索引。假设,文本包含 5 次“cat”和 7 次“链接”,我必须为每个具有不同 URL 的 Click-able span 设置。 indexOf 返回第一次出现,但其他的呢?我可以在字符串中获得第 n 次出现的单词,但我很难跟踪所有这些单词。我希望你了解这里的情况。 @法希姆
    • 我不想链接“Cat Link 1”或“Cat Link 2”。我想分别链接它们,分别“Cat”和“Link”,以及它们的所有出现。如果我无法向您解释情况,我很抱歉。
    • 你仍然没有得到我想说的。无论如何,谢谢:)
    【解决方案2】:

    如果您无法以编程方式找到链接中的差异,那么您就不能指望其他任何东西能够做到这一点。作为开发者,您需要一个系统。

    您需要能够识别可点击范围 - 由于链接是唯一的,因此标识它们的文本也必须是唯一的。这很可能对您的用户来说是个问题。

    您可以获得一个有序的 URL 列表,然后如果链接无法区分,只需按照您收到的顺序使用它们。或者,您需要更改创建链接的规则或它们的显示顺序。

    【讨论】:

    • 感谢您的评论!我明白你在说什么。但是从服务器端提供这种数据,如果可能的话,我也必须处理这种情况。如果标识链接的文本相同怎么办?必须有一种方法可以为具有不同 URL 的两种文本提供服务。
    • 如果文本相同,你如何与每个字符串关联哪个URL?您必须有一个系统才能做出正确的决定?
    【解决方案3】:

    一种简单的方法是在链接之前包含一个标识符,例如/*/,然后使用它找到链接的开始和结束位置。完成后,首先将标识符替换为 "",然后点击离开。

    【讨论】:

    • 你能再解释一下你在说什么吗?
    • 所以说你的文字是“这是一个猫链接,这是另一个猫链接”而不是发送一个链接“这是一个猫/*/链接,这是另一个猫/*/链接”作为设置可点击点的标记..然后检测此标记的位置以获取可点击文本区域的开始和结束位置。一旦检测到简单地删除标记​​span>
    【解决方案4】:

    我有这样的字符串 “您使用 orderId {b1j2gh4b} 订购的产品已被 bla bla sotre 用电话号码 (1234124124) 认领”

    我正在使用这些大括号来找出orderID电话号码的索引

     String notificationMessage = mArrListNotification.get(position).getMessage();
                boolean isPhoneNumberAvailable = false, isOrderIdAvailable = false;
                int phoneStartIndex = 0, phoneEndIndex = 0, orderIdStartIndex = 0, orderIdEndIndex = 0;
    
        //getting index on the basis of braces added to text
                if (notificationMessage.contains("(")) {
                    isPhoneNumberAvailable = true;
                    phoneStartIndex = notificationMessage.indexOf("(");
                    phoneEndIndex = notificationMessage.indexOf(")");
                }
                if (notificationMessage.contains("{")) {
    
                    orderIdStartIndex = notificationMessage.indexOf("{");
                    orderIdEndIndex = notificationMessage.indexOf("}");
    
                }
    
                // we got the index so remove braces
                notificationMessage = notificationMessage.replace("(", " ");
                notificationMessage = notificationMessage.replace(")", " ");
                notificationMessage = notificationMessage.replace("{", " ");
                notificationMessage = notificationMessage.replace("}", " ");
    
                viewHolder.txtNotificationMessage.setText(notificationMessage, TextView.BufferType.SPANNABLE);
                Spannable mySpannablePhoneNumber = (Spannable) viewHolder.txtNotificationMessage.getText();
                Spannable mySpannableOrderID = (Spannable) viewHolder.txtNotificationMessage.getText();
                ClickableSpan mySpanPhoneClick = new ClickableSpan() {
                    @Override
                    public void onClick(View widget) {
    
                        currentPosition = (Integer) widget.getTag();
    
                        String message = mArrListNotification.get(currentPosition).getMessage();
                        int startIndex = message.indexOf("(");
                        int endIndex = message.indexOf(")");
                        phoneNumber = message.substring(startIndex + 1, endIndex);
    
         Log.i("Phone Number", phoneNumber clicked)
    
                    }
                };
                ClickableSpan mySpanOrderClick = new ClickableSpan() {
                    @Override
                    public void onClick(View widget) {
                        currentPosition = (Integer) widget.getTag();
    
                        String message = mArrListNotification.get(currentPosition).getMessage();
                        int startIndex = message.indexOf("{");
                        int endIndex = message.indexOf("}");
                        String orderID = message.substring(startIndex + 1, endIndex);
        // Log.i("Order id", orderID  clicked)
    
                    }
                };
                if (isPhoneNumberAvailable) {
                    mySpannablePhoneNumber.setSpan(mySpanPhoneClick, phoneStartIndex + 1, phoneEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
                if (isOrderIdAvailable) {
                    mySpannableOrderID.setSpan(mySpanOrderClick, orderIdStartIndex + 1, orderIdEndIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-07
      • 2016-12-11
      • 2014-01-18
      • 1970-01-01
      • 2016-09-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多