3

I would like to link some text on a TextView to an Activity. This is the TextView that I have:

<TextView
     android:id="@+id/termsLink"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:text="@string/terms"
     android:layout_weight="4"/>

where @string/terms is:

<string name="terms">Accept <a href="#">terms & conditions.</a>.</string>

If I had a link to a webpage I would do it like this:

TextView link = (TextView) findViewById(R.id.termsLink);
link.setMovementMethod(LinkMovementMethod.getInstance());

but I do not know how to start an Activity when I press the link as when it is a real link (that it links a webpage).

EDIT: Please note that I do not have to handle the onClick event in the full text because the link is only on the part "terms & conditions".

EDIT 2: I have tried using two TextView as suggested on the comments and one of the answers below to make the same effect. But sometimes (depending on the screen) the "terms & conditions" part occupy two lines because it does not fill properly on the available space so the second line it is shown on the second TextView and not on the begining of the second line.

The effect is similar to this:

Accept terms & 
       conditions.

and I would like that it would be like this:

Accept terms &
conditions.

Thanks in advance!

Francisco Romero
  • 12,787
  • 22
  • 92
  • 167
  • do you want to open an Activity by clicking on some link in webView? – nutella_eater Aug 09 '16 at 08:47
  • Can you be a bit more clear about what you're trying to achieve? Does clicking on the TextView fulfill your needs? :) Also, try adding `android:autoLink="all"` to see if that makes the link clickable, and maybe catch that with the regular TextView click, dunno... – Vucko Aug 09 '16 at 08:47
  • @Vucko I have another class that has its own layout with all the terms & conditions. I only want that in the part of the text that the link is, a new Activity (called Conditions) will be started. – Francisco Romero Aug 09 '16 at 08:49
  • direct put onlick event on textView .......... i think your problem will be solved ........ – sushildlh Aug 09 '16 at 08:51
  • 1
    @sushildlh It probably wont be solved, as he want's to click just on "terms & conditions" – jpact Aug 09 '16 at 08:51
  • @creck Yes, exactly was I was going to put. It will handle the onclick event in all the text and not in the part "terms & conditions". – Francisco Romero Aug 09 '16 at 08:52
  • http://stackoverflow.com/questions/1697084/handle-textview-link-click-in-my-android-app – Maciej Sikora Aug 09 '16 at 08:53
  • 1
    divide your text into 2 different textView . It is much easier also . – sushildlh Aug 09 '16 at 08:53
  • I thought the same thing as @sushildlh about 2 TextViews :) – Vucko Aug 09 '16 at 09:00
  • Use Customized Spannable Textview. http://stackoverflow.com/a/5184835/403255 – Vinothkumar Arputharaj Aug 09 '16 at 09:07
  • @Error404 I added you an answer below, that should work even for translated resources – jpact Aug 09 '16 at 09:13
  • @Vucko Yes, I also have thought about it but look at my second edit to see what is the problem that I am getting. It does not display correctly the text when it is a small screen. – Francisco Romero Aug 09 '16 at 09:30
  • 2
    int the manifest, for your target `Activity` add `intent-filter` tag with `action` set to `android.intent.action.VIEW`, `category` set to `android.intent.category.DEFAULT` and `data` with `scheme` set to `testscheme`, now you can use it like this: `Accept terms..` – pskink Aug 09 '16 at 09:40
  • @pskink It shows me a message that says: "Select one option. None application can do this action." (I have translated it myself so it may change a bit). – Francisco Romero Aug 09 '16 at 10:06
  • 1
    http://pastebin.com/jRa0VzSg – pskink Aug 09 '16 at 10:08
  • 1
    @pskink Ok, I was almost near, but I had a mistake because I thought `data` was a tag as `intent-filter`. Thank you very much! I think you should add it as an answer because it is more simpler than the answers that are right now. – Francisco Romero Aug 09 '16 at 10:13

3 Answers3

1

Create a helper class with inner onClick listener

public class ClickSpan extends ClickableSpan {

    private String url;
    private OnClickListener listener;

    public ClickSpan(String url, OnClickListener listener) {
        this.url = url;
        this.listener = listener;
    }

    @Override
    public void onClick(View widget) {
        if (listener != null) listener.onClick(url);
    }

    public interface OnClickListener {
        void onClick(String url);
    }
}

Then convert existing span into clickable one

public static Spannable createClickableSpans(Spanned original,     ClickSpan.OnClickListener listener) {
    SpannableString result = new SpannableString(original);
    URLSpan[] spans = result.getSpans(0, result.length(), URLSpan.class);

    for (URLSpan span : spans) {
        int start = result.getSpanStart(span);
        int end = result.getSpanEnd(span);
        int flags = result.getSpanFlags(span);

        result.removeSpan(span);
        result.setSpan(new ClickSpan(span.getURL(), listener), start, end, flags);
    }

    return result;
}

So, final usage would be like

TextView link = (TextView) findViewById(R.id.termsLink);
link.setMovementMethod(LinkMovementMethod.getInstance());
link.setText(createClickableSpans((Spanned)link.getText(), new ClickSpan.OnClickListener(){
    @Override
    public void onClick(String url){
        //Handle URL on text view click
    }
}));
Aftab Abbas
  • 47
  • 1
  • 10
jpact
  • 1,042
  • 10
  • 23
0

You should probably separate the text into 2 text views one with the terms and condition and one with just the accept.It would make things cleaner and easier. The following TextView is assuming its just for accept.

In the layouts corresponding java class(example: activity_main -> MainActivity):

public void start_activity(View view){
   Intent newActivityIntent = new Intent(this,NewActivity.class);
   startActivity(newActivityIntent);
}

NewActivity.class is just the name of the activity you want to start.

public class MainActivity extends AppCompatActivity {

    protected void onCreate(Bundle savedInstanceState) {
         ....
    }

    public void start_activity(View view){
         .....
    } 
}
  • But if you use `onClick` event you are handling the `onClick` event in the full text, and not only on the part "terms & conditions". – Francisco Romero Aug 09 '16 at 09:08
  • yh thats true I forgot to add the bit at the top about separating the text into 2 views – KeaneDaSilva Aug 09 '16 at 09:12
  • The problem I saw is that "terms & conditions" do not fill properly and have to occupy two lines, it will occupy the second line of the second TextView so it makes a strange behaviour. – Francisco Romero Aug 09 '16 at 09:23
  • You can set the textView to change size depending on the dimensions of the device . Here is a link to a answer that can help http://stackoverflow.com/questions/9494037/how-to-set-text-size-of-textview-dynamically-for-different-screens – KeaneDaSilva Aug 09 '16 at 09:57
  • Simple in the dimens.xml in the values folder. `21sp` `` – KeaneDaSilva Aug 09 '16 at 10:05
0

To make only part of a TextView clickable, you can use a spannable inside the TextView and set an onClick event listener. From here, you launch the activity with an intent as usual. You can limit the clickable section of the text by specifying the character positions (start to end)

Checkout this answer by @becomputer06

How to set the part of the text view is clickable

Community
  • 1
  • 1
fersarr
  • 3,399
  • 3
  • 28
  • 35
  • That probably wont work if he translates his resources, as position of "word" in translated text will be different – jpact Aug 09 '16 at 09:07
  • that is true. If you are going to translate the text something extra will be needed – fersarr Aug 09 '16 at 09:09