20

How to move to another view by click on text view with two different words. this is the string i am using.

By clicking Sign Up, you are indicating that you have read and agree to the 
Term of Use and Privacy Policy.

i want to make these two words (Term of Use, Privacy Policy) in different color and clickable..

i know ho to make color for a particular word. i want to make it clickable .

RajaReddy PolamReddy
  • 22,428
  • 19
  • 115
  • 166
  • Hi, how to remove this "widget", and refresh edittext. ssb.setSpan(new ClickableSpan() { @Override public void onClick(View widget) { // how to remove this "widget", and refresh edittext. } }, idx1, idx2, 0); – Sakthivel Appavu Jul 04 '15 at 07:58

5 Answers5

60

I finally figured it out how to have multiple clickable parts in a TextView. It is important that they all have their own ClickableSpan! That is where I went wrong the first time testing it. If they have the same ClickableSpan instance, only the last set span is remembered.

I created a String with the required clickable area's surrounded by "[" and "]".

String sentence = "this is [part 1] and [here another] and [another one]";

and here is the set TextView, the setMovementMehthod is also mandatory:

textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(addClickablePart(sentence), BufferType.SPANNABLE);

I have created this function, which will handle the creation of the clickable area's:

private SpannableStringBuilder addClickablePart(String str) {
    SpannableStringBuilder ssb = new SpannableStringBuilder(str);

    int idx1 = str.indexOf("[");
    int idx2 = 0;
    while (idx1 != -1) {
        idx2 = str.indexOf("]", idx1) + 1;

        final String clickString = str.substring(idx1, idx2);
        ssb.setSpan(new ClickableSpan() {

            @Override
            public void onClick(View widget) {
                Toast.makeText(getView().getContext(), clickString,
                        Toast.LENGTH_SHORT).show();
            }
        }, idx1, idx2, 0);
        idx1 = str.indexOf("[", idx2);
    }

    return ssb;
}
Boy
  • 7,010
  • 4
  • 54
  • 68
15

Based on Boy's response (and thank you for your response which helped me a lot), here is another way I implemented it without this '[' and ']' chars using an inner class to describe clickable words :

import java.util.List;

import android.content.Context;
import android.text.SpannableStringBuilder;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.util.AttributeSet;
import android.widget.TextView;

/**
 * Defines a TextView widget where user can click on different words to see different actions
 *
 */
public class ClickableTextView extends TextView {

    public ClickableTextView(Context context) {
        super(context);
    }

    public ClickableTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ClickableTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void setTextWithClickableWords(String text, List<ClickableWord> clickableWords) {
        setMovementMethod(LinkMovementMethod.getInstance());
        setText(addClickablePart(text, clickableWords), BufferType.SPANNABLE);
    }

    private SpannableStringBuilder addClickablePart(String str, List<ClickableWord> clickableWords) {
        SpannableStringBuilder ssb = new SpannableStringBuilder(str);

        for (ClickableWord clickableWord : clickableWords) {
            int idx1 = str.indexOf(clickableWord.getWord());
            int idx2 = 0;
            while (idx1 != -1) {
                idx2 = idx1 + clickableWord.getWord().length();
                ssb.setSpan(clickableWord.getClickableSpan(), idx1, idx2, 0);
                idx1 = str.indexOf(clickableWord.getWord(), idx2);
            }
        }

        return ssb;
    }

    public static class ClickableWord {
        private String word;
        private ClickableSpan clickableSpan;

        public ClickableWord(String word, ClickableSpan clickableSpan) {
            this.word = word;
            this.clickableSpan = clickableSpan;
        }

        /**
         * @return the word
         */
        public String getWord() {
            return word;
        }

        /**
         * @return the clickableSpan
         */
        public ClickableSpan getClickableSpan() {
            return clickableSpan;
        }
    }
}

Hope this may help someone

EDIT : how to change link color and remove underline:

Create and use your own implementation of ClickableSpan like this :

//a version of ClickableSpan without the underline
public static class NoUnderlineClickableSpan extends ClickableSpan {
    private int color = -1;

    public void setColor(int color) {
        this.color = color;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        ds.setUnderlineText(false);
        if (this.color != -1) {
            ds.setColor(this.color);
        }
    }
}
saschoar
  • 8,150
  • 5
  • 43
  • 46
phyzalis
  • 1,236
  • 1
  • 13
  • 24
  • Nice! Great I could help you out with this...I think I will be using your class then again for my project :) – Boy Mar 03 '14 at 08:04
  • Thank you, and @Boy Working perfect. Words look underlined and blue. How can i style it? – Göksel Güren Nov 02 '14 at 06:04
  • You must define a custom ClickableSpan to use in ClickableWord. I will edit my response and add it – phyzalis Nov 04 '14 at 01:44
  • I do not know. Probably now I would create my own custom view to handle this if I would want to style it differently. Not sure though. Been a few years when I wrote this :) – Boy Nov 04 '14 at 05:58
  • 1
    Look at the NoUnderlineClickableSpan class I wrote in my edited response. I didn't find any other way for the underline. – phyzalis Nov 04 '14 at 08:42
8

It's much simpler to use HTML with links in TextView than creating multiple TextViews, taking care about layout, listeners etc.

In your activity or fragment:

    TextView mText = (TextView) findViewById(R.id.text_linkified);
    mText.setText(Html.fromHtml("Open <a href='myapp://my-activity'>My Activity</a> or" +
            " <a href='myapp://other-activity'>Other Activity</a>"));
    mText.setMovementMethod(LinkMovementMethod.getInstance());

In manifest

    <activity android:name=".MyActivity">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:scheme="myapp" android:host="my-activity"/>
        </intent-filter>
    </activity>
    <activity android:name=".MyOtherActivity">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:scheme="myapp" android:host="other-activity" />
        </intent-filter>
    </activity>
pawelzieba
  • 16,082
  • 3
  • 46
  • 72
  • 1
    i am not using url here just text i want to open new activity by clicking on text. – RajaReddy PolamReddy Mar 07 '12 at 04:36
  • If the text is not changing, for example it's declared in strings.xml then this is the way to do it. Just declare "clickable" texts as a url with actions pointing to your activities. In result you'll get just text which is opening new activity on click, depends on what part of text you're clicking. – pawelzieba Mar 07 '12 at 15:31
  • I have edited answer because a troll was down voting. – pawelzieba Nov 01 '13 at 15:41
  • And if you want to pass Parcelable object to your new Activity? – phyzalis Nov 04 '14 at 01:59
2

I recommend this library: https://github.com/klinker24/Android-TextView-LinkBuilder

it fits your requirement very well.

A quick overview:

enter image description here

copied form project's readme:

  • Specify long and short click actions of a specific word within your TextView
  • Provide user feedback by highlighting the text when the user touches it Match single strings or use a regular expression to set clickable links to any text conforming to that pattern
  • Change the color of the linked text
  • Modify the transparency of the text's highlighting when the user touches it
  • Set whether or not you want the text underlined

The main advantage to using this library over TextView's autolink functionality is that you can link anything, not just web address, emails, and phone numbers. It also provides color customization and touch feedback.

fangzhzh
  • 2,172
  • 21
  • 25
0

In ClickableTextView implementation, what happens if string got a word with repeated ? suppose for example string is "I'm clickable and also this is clickable" then both the strings should be changed to Spannable string but it fails it that scenario, only one will be changed to spannable string.