【问题标题】:Linkify() - activating linksLinkify() - 激活链接
【发布时间】:2012-09-11 00:08:21
【问题描述】:

我在弹出对话框中添加了指向 [方括号] 包围的文本的链接。然而,这些链接是不可点击的(当它们被按下时没有任何反应)。我不知道为什么(!)

这是我的对话框活动:

public void popupDefinition(CharSequence term, LinkedHashMap<String, String> dictionaryMap){
    SpannableString definition = new SpannableString(dictionaryMap.get(term)); // grab the definition by checking against the dictionary map hash
    Linkify.addLinks(definition, pattern, scheme); // find text in square brackets, add links

    AlertDialog alertDialog = new AlertDialog.Builder(ListProjectActivity.this).create(); // create a dialog box
    alertDialog.setMessage(definitionFormatted); // set dialog box message
    alertDialog.show(); // actually display the dialog box
    }

'scheme'和'pattern'前面已经定义了,如下:

final static Pattern pattern = Pattern.compile("\\[[^]]*]"); // defines the fact that links are bound by [square brackets]
final String scheme = "http://example.com/"; // THIS IS NOT WORKING

为什么,当我点击出现的链接时(它们带有很好的蓝色下划线),它们没有引起任何响应吗?

我实际上并没有尝试启动 URL 链接(当它发生时,我将重定向 ACTION_VIEW 意图),但我需要确认某种响应正在发生,然后才开始...

【问题讨论】:

    标签: android linkify


    【解决方案1】:

    我实际上并没有尝试启动 URL 链接

    由于您不需要使用 URL,因此不必费心尝试创建自定义 Linkify 方案,因为它只会创建 URLSpans。您只是想从 TextView 中的关键字启动 Activity。正如我在您的一个类似但重复的问题中所述,我将使用自定义跨度,引入 ActivitySpan:

    public class ActivitySpan extends ClickableSpan {
        String keyword;
        public ActivitySpan(String keyword) {
            super();
            this.keyword = keyword;
        }
    
        @Override
        public void onClick(View v) {
            Context context = v.getContext();
            Intent intent = new Intent(context, AnotherActivity.class);
            intent.putExtra("keyword", keyword);
            context.startActivity(intent);
        }
    }
    

    这里没有花里胡哨的东西,这个跨度需要一个[keyword],你用括号括起来并将它传递给另一个活动。

    虽然由于 URLSpan 我不喜欢使用 Linkify 的想法,但它的模式匹配和跨度创建很棒,所以我复制并修改了它:

    private void addLinks(TextView textView, Pattern pattern) {
        SpannableString spannable = SpannableString.valueOf(textView.getText());
        Matcher matcher = pattern.matcher(spannable);
    
        // Create ActivitySpans for each match
        while (matcher.find())
            spannable.setSpan(new ActivitySpan(matcher.group()), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    
        // Set new spans in TextView
        textView.setText(spannable);
    
        // Listen for spannable clicks, if not already
        MovementMethod m = textView.getMovementMethod();
        if ((m == null) || !(m instanceof LinkMovementMethod)) {
            if (textView.getLinksClickable()) {
                textView.setMovementMethod(LinkMovementMethod.getInstance());
            }
        }
    }
    

    请注意,此方法不会删除每个关键字周围的 [brackets],但您可以在 while 循环中轻松执行此操作。

    要使用它,只需将 TextView 和 Pattern 传递给 addLinks() in onCreate()瞧!


    一个适合您的工作示例:

    public class Example extends Activity {
        Pattern pattern = Pattern.compile("\\[[^]]*]");
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            popupDefinition("Example: A [pattern] or [model], as of something to be [imitated] or [avoided]");
        }
    
        // It seems like you can call "popupDefinition(dictionaryMap.get(term));" rather than pass both.  
        public void popupDefinition(String string){
            SpannableString spannable = new SpannableString(string);
            Matcher matcher = pattern.matcher(spannable);
    
            // Create ActivitySpans for each match
            while (matcher.find())
                spannable.setSpan(new ActivitySpan(matcher.group()), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    
            // Create a new TextView with these spans and enable the clickable links
            TextView textView = new TextView(this);
            textView.setText(spannable);
            textView.setMovementMethod(LinkMovementMethod.getInstance());
    
            // Create and display an AlertDialog with this TextView
            AlertDialog alertDialog = new AlertDialog.Builder(this)
                    .setView(textView)
                    .create(); 
            alertDialog.show(); 
        }
    
    
        public class ActivitySpan extends ClickableSpan {
            String keyword;
            public ActivitySpan(String keyword) {
                super();
                this.keyword = keyword;
            }
    
            @Override
            public void onClick(View v) {
                Context context = v.getContext();
                Toast.makeText(context, keyword, Toast.LENGTH_SHORT).show();
            }
        }
    }
    

    【讨论】:

    • 我的输入文本当前是一个字符串。如何将其转换为 TextView?
    • 我不太明白这个问题。您在将 Spannable 传递给 AlertDialog 时遇到问题吗?
    • 我的意思是 - 我进入 addLinks() 的输入文本是一个字符串 - 我从 HashMap 中检索它。问题是我无法将字符串放入上述解决方案 - 我知道我必须在这里遗漏一些基本的东西......据我了解,TextView 是一个文本编辑器对象?
    • 只需将字符串传递给addLinks()第一行中的SpannableString.valueOf()即可。
    • 为了澄清遇到此问题的其他人,我无法单击链接的原因是因为我使用的是 setMessage() 而不是 setView()。设置为消息会删除文本链接做除了看起来漂亮以外的任何事情的能力。
    猜你喜欢
    • 2017-10-30
    • 1970-01-01
    • 2019-07-22
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多