在Android中TextView中可点击的单词

38

我有一个TextView,其中的文本是动态变化的。这个文本包含像<a href='myWord'>myWord</a>这样的字符串。我想要在单击这个“链接”之后,在同一个活动中的EditText中显示myWord。

这是我的代码:

txt.setText(Html.fromHtml("...<a href='link'>link</a>..."));
txt.setMovementMethod(LinkMovementMethod.getInstance());

对于 href 属性中的 URL,它可以正常工作,但是其他格式会出现错误。

我在 StackOverflow 上找到了很多类似的问题,但它们都是关于网址链接的。在我的应用程序中,我想在活动内创建“链接”。 通常,如果需要的话,我可以将标签更改为其他标签...

请帮忙! 谢谢!

-----已解决----- 感谢 Jacob Phillips 的建议!

也许将来会有人感兴趣。 这是代码:

//This is my string;
String str = "<b>Text</b> which contains one <a href='#'>link</a> and another <a href='#'>link</a>";
//TextView;
TextView txt = new TextView(this);
//Split string to parts:                                        
String[] devFull = data[v.getId()][1].split("<a href='#'>");
//Adding first part:
txt.append(Html.fromHtml(devFull[0]));
//Creating array for parts with links (they amount always will devFull.length-1):
SpannableString[] link = new SpannableString[devFull.length-1];
//local vars:
ClickableSpan[] cs = new ClickableSpan[devFull.length-1];
String linkWord;
String[] devDevFull = new String[2];

for(int i=1; i<devFull.length; i++){
    //obtaining 'clear' link
    devDevFull = devFull[i].split("</a>");
    link[i-1] = new SpannableString(devDevFull[0]);
    linkWord = devDevFull[0];
    cs[i-1] = new ClickableSpan(){
        private String w = linkWord;
        @Override
        public void onClick(View widget) {
            // here you can use w (linkWord)
        }
    };
    link[i-1].setSpan(cs[i-1], 0, linkWord.length(), 0);
    txt.append(link[i-1]);
    try{
        txt.append(Html.fromHtml(devDevFull[1]));
    }
    catch(Exception e){}
}
6个回答

45

这应该就可以了。只需在 OnClickListener 中更改您的 EditText 的文本即可。可能可以缩减代码,但这应该可以工作。

private void foo() {
    SpannableString link = makeLinkSpan("click here", new View.OnClickListener() {          
        @Override
        public void onClick(View v) {
            // respond to click
        }
    });

    // We need a TextView instance.        
    TextView tv = new TextView(context);   

    // Set the TextView's text     
    tv.setText("To perform action, ");

    // Append the link we created above using a function defined below.
    tv.append(link);

    // Append a period (this will not be a link).
    tv.append(".");

    // This line makes the link clickable!
    makeLinksFocusable(tv);
}

/*
 * Methods used above.
 */

private SpannableString makeLinkSpan(CharSequence text, View.OnClickListener listener) {
    SpannableString link = new SpannableString(text);
    link.setSpan(new ClickableString(listener), 0, text.length(), 
        SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);
    return link;
}

private void makeLinksFocusable(TextView tv) {
    MovementMethod m = tv.getMovementMethod();  
    if ((m == null) || !(m instanceof LinkMovementMethod)) {  
        if (tv.getLinksClickable()) {  
            tv.setMovementMethod(LinkMovementMethod.getInstance());  
        }  
    }  
}

/*
 * ClickableString class 
 */

private static class ClickableString extends ClickableSpan {  
    private View.OnClickListener mListener;          
    public ClickableString(View.OnClickListener listener) {              
        mListener = listener;  
    }          
    @Override  
    public void onClick(View v) {  
        mListener.onClick(v);  
    }        
}

谢谢您的回答。我很抱歉可能问了一个愚蠢的问题,但是ClickableString()类是什么? - lubart
我刚刚添加了它。我使用了一个修改过的版本的这个答案来回答一个类似的问题。 - Jacob Phillips
谢谢!但是它不起作用 :( 在ClickableString类中,我在mListener.onClick(v);行上遇到了一个错误: The method onClick(DialogInterface, int) in the type DialogInterface.OnClickListener is not applicable for the arguments (View) 我不知道该如何纠正它。你有什么想法吗? 无论如何,还是谢谢! - lubart
你必须使用 View.OnClickListener 而不是 DialogInterface.OnClickListener。请接受为答案 :) - Jacob Phillips
是的,我尝试使用View.OnClickListener,但出了些问题。我改用了ClickableSpan()而不是ClickableString(),这很有帮助。谢谢! - lubart
显示剩余2条评论

18
更好的方法是。
   SpannableString ss = new SpannableString("Android is a Software stack");
    ClickableSpan clickableSpan = new ClickableSpan() {
        @Override
        public void onClick(View textView) {
            startActivity(new Intent(MyActivity.this, NextActivity.class));
        }
    };
    ss.setSpan(clickableSpan, 22, 27, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//where 22 and 27 are the starting and ending index of the String. Now word stack is clickable 
// onClicking stack it will open NextActiivty

    TextView textView = (TextView) findViewById(R.id.hello);
    textView.setText(ss);
    textView.setMovementMethod(LinkMovementMethod.getInstance());

if they are multiple clicks - Prasad
请查看以下两个链接:https://dev59.com/PGLVa4cB1Zd3GeqPuj8X#9982588 和 https://dev59.com/dmEh5IYBdhLWcg3w0GOx#22006998。 - Zar E Ahmer

3
您可以使用以下代码:
 SpannableString myString = new SpannableString(Html.fromHtml("Please "+"<font color=\"#F15d36\"><u>"+"login"+"</u></font>" +" or "+ "<font color=\"#F15d36\"><u>"+"sign up"+ "</u></font>"+" to begin your YupIT experience"));

        ClickableSpan clickableSpan = new ClickableSpan() {
            @Override
            public void onClick(View textView) {
                Toast.makeText(getContext(),"dfsgvdfs",Toast.LENGTH_SHORT).show();
            }
        };

        ClickableSpan clickableSpan1 = new ClickableSpan() {
            @Override
            public void onClick(View textView) {
                Toast.makeText(getContext(),"dfsgvdfs",Toast.LENGTH_SHORT).show();
            }
        };

        myString.setSpan(clickableSpan,6,12,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        myString.setSpan(clickableSpan1,15,23,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        myString.setSpan(new ForegroundColorSpan(Color.parseColor("#F15d36")),6, 12, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        myString.setSpan(new ForegroundColorSpan(Color.parseColor("#F15d36")),15,23, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);


        tvFound.setMovementMethod(LinkMovementMethod.getInstance());
        tvFound.setText(myString);

0

为了完整回答,需要混合多个答案;

private void textAreaInit()
{
    String str = "<a href='#'>Link 1</a> and <a href='#'>Link2</a> is here.";

    TextView tv = mConfirmText;  
    String[] devFull = str.split("<a href='#'>");


    tv.append(Html.fromHtml(devFull[0]));

    SpannableString[] link = new SpannableString[devFull.length-1];

    ClickableSpan[] cs = new ClickableSpan[devFull.length-1];
    String linkWord;
    String[] devDevFull = new String[2];

    for(int i=1; i<devFull.length; i++)
    {
        //obtaining 'clear' link
        devDevFull = devFull[i].split("</a>");
        link[i-1] = new SpannableString(devDevFull[0]);
        linkWord = devDevFull[0];
        final String a = linkWord;
        cs[i-1] = new ClickableSpan()
        { 
            private String w = a;
            @Override
            public void onClick(View widget) {

                if(w.equals("Link 1"))
                {
                    Intent intent = new Intent(PrintPropertiesActivity.this, ViewerAcivity.class);
                    intent.putExtra("title", "Link1");
                    intent.putExtra("uri", "link1");
                    intent.putExtra("type", "1");
                    startActivity(intent);
                }
                else
                {
                    Intent intent = new Intent(PrintPropertiesActivity.this, ViewerAcivity.class);
                    intent.putExtra("title", "Link2");
                    intent.putExtra("uri", "link2");
                    intent.putExtra("type", "2");
                    startActivity(intent);
                }
            }
        };
        link[i-1].setSpan(cs[i-1], 0, linkWord.length(), 0);
        tv.append(link[i-1]);
        try{
            tv.append(Html.fromHtml(devDevFull[1]));
        }
        catch(Exception e){}
    }


    makeLinksFocusable(tv);
}

private void makeLinksFocusable(TextView tv) {
    MovementMethod m = tv.getMovementMethod();  
    if ((m == null) || !(m instanceof LinkMovementMethod)) {  
        if (tv.getLinksClickable()) {  
            tv.setMovementMethod(LinkMovementMethod.getInstance());  
        }  
    }  
}

0
我知道的最好的解决方法是创建自己的Button类。您可以使Button具有透明背景,以便用户只能看到文本。然后,当按下按钮时,将按钮的TextColor和TextStyle更改为较暗的颜色和带下划线的样式。这将完全像链接一样工作。然后,您可以使用startActivity转到适当的活动。您不应该使用超链接来连接应用程序中的其他活动。

谢谢您的回答,但我不能使用按钮。我的TextView中的文本不是静态的,我无法知道下一次我的“链接”将出现在哪里。文本来自数据库,我需要以某种方式标记我的linkWord。我正在使用<a>标签... - lubart

0

我的个人意见是创建第二个TextView来包含你想要作为链接的文本。然后你可以在这个第二个TextView的onClick事件中执行你的操作。另外,正如zzzzzzzzzz所说,你可以选择在文本被点击后更改其字体属性。


1
谢谢您的回答,但我不能将我的TextView分成几个部分,我需要一个完整的TextView... - lubart
为了真正创建一个内部应用程序链接(如果我理解正确的话),我认为唯一的方法是调用OnClick方法,而且我不认为可以在TextView的特定部分上执行此操作。祝你好运。 - testingtester

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接