Home » Android » clickable word inside TextView in android

clickable word inside TextView in android

Posted by: admin April 23, 2020 Leave a comment

Questions:

I have TextView with text that changed dynamically. This text contain strings like <a href='myWord'>myWord</a>. I want that after click to this “link” myWord appear in the EditText in the same activity.

This is my code:

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

It’s work well for URLs inside href attribute, but there is an error for another format.

I found a lot of similar questions on the StackOverflow but all of them were about url links. In my app I want create “link” inside activity.
In general, I can change tag to some another if it’s depend…

Please help me!
Thank you!

—–SOLVED—–
Thank you Jacob Phillips for idea!

May it will be interesting someone in future.
This is a code:

//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){}
}
How to&Answers:

This should do the trick. Just change your edittext’s text in the OnClickListener. It may be able to be reduced but this should work.

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);  
    }        
}

Answer:

Better approach is

   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());

Answer:

You can use below code;

 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);

Answer:

The best workaround I know is to create your own Button class. You could make the Button have a transparent background so that only the text is seen by the user. Then when the Button is pressed down change the TextColor and TextStyle of the button to be a darker color and underlined. This will work exactly as a link does. You can then use startActivity to go to the appropriated activity. You should not use hyperlinks to connect to other activities within your application.

Answer:

My personal opinion would be to make a second textview containing the text that you want to be your link. Then you could do your action in the onClick of this second textView . Also as zzzzzzzzzzz stated above, you could choose to change the font properties of that text to whatever you want once it has been clicked.

Answer:

To make it full answer with mixing answers;

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());  
        }  
    }  
}