11

The following code shows how I'm applying a pressed state using a custom ClickableSpan and selector. However, the pressed state is applied whenever I press anywhere on the TextView, not just the ClickableSpan. How do I stop this?

Note: it does not call onClick, but does apply state_pressed from the selector. I want it to do neither.

MyView.java

SpannableString spanned = new SpannableString("click here");
spannable.setSpan(new MyClickableSpan() {
        @Override
        public void onClick(View widget) {
            doSomething();
        }
    }, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spanned);
textView.setMovementMethod(LinkMovementMethod.getInstance());

MyClickableSpan.java

public abstract class MyClickableSpan extends ClickableSpan {

    @Override
    public abstract void onClick(View view);

    @Override
    public void updateDrawState(TextPaint ds) {
        super.updateDrawState(ds);
        ds.setUnderlineText(false);
    }
}

the TextView

<TextView
    android:id="@+id/my_text_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@android:color/white"
    android:textColorLink="@color/my_selector" />

my_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="@color/my_color_pressed" />
    <item android:color="@color/my_color" />
</selector>

Edit note: Added TextView code

Fifer Sheep
  • 2,900
  • 2
  • 30
  • 47

5 Answers5

3

Next example works as you're expecting:

    Spannable span = SpannableStringBuilder.valueOf("Hello clickable span!");
    span.setSpan(new MyClickableSpan(), 6, 15, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    mTextView.setText(span);
    mTextView.setMovementMethod(LinkMovementMethod.getInstance());

Now span applied: enter image description here

Here's MyClickableSpan() that's only show Snackbar to indicate that "click" is handled:

class MyClickableSpan extends ClickableSpan {

    @Override
    public void onClick(View widget) {
        Snackbar.make(getWindow().findViewById(android.R.id.content), "Click on span!", Snackbar.LENGTH_LONG).show();
    }
}

We've got:

  1. Click/tap outside the "spanned" text will do nothing
  2. Click/tap on "spanned" part of text will show Snackbar

enter image description here

That's it. Please let me know if you need any additional info.

Stas Lelyuk
  • 538
  • 6
  • 19
1

You have to set MovementMethod to the TextView which has the Span.

textView.setMovementMethod(LinkMovementMethod.getInstance());
Bob
  • 13,447
  • 7
  • 35
  • 45
  • Hi, sorry I should have added the TextView code I already have, as I already set a movement method. I have added this code now. – Fifer Sheep May 11 '16 at 09:40
1

You can refer below code I have tested it.

 String s = "This is custom string click Here";
    SpannableString spanned = new SpannableString(s);
    spanned.setSpan(new MyClickableSpan() {
        @Override
        public void onClick(View widget) {
            Log.i("main", "Link clicked");
        }
    }, s.length() - 10, s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    textView.setText(spanned);
    textView.setMovementMethod(LinkMovementMethod.getInstance());

TextView

 <TextView
    android:id="@+id/my_text_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColor="@drawable/my_selector"
    android:textColorLink="@color/colorPrimary" />

You can use tutorial here

Rax
  • 1,347
  • 3
  • 20
  • 27
0

In your code you have define

 android:textColor="@android:color/white" 

instead of this you have to define your selector like below

 android:textColor="@drawable/my_selector"

rest of code is as it is you have to changed only one line that android:textColor="@drawable/my_selector" that i explain above.

Darshan Mistry
  • 3,294
  • 1
  • 19
  • 29
  • The `textColor` attribute is overridden by the `textColorLink` attribute - so this doesn't help me. The non-link text color is fine. – Fifer Sheep May 17 '16 at 09:35
-1

You can do this way:

TextView textView = (TextView)findViewById(R.id.textView);
Spannable span = Spannable.Factory.getInstance().newSpannable("test link span");
span.setSpan(new ClickableSpan() {
   @Override
   public void onClick(View v) {
        Log.i("main", "Link clicked");
        Toast.makeText(HomeScreenActivity.this, "link clicked", Toast.LENGTH_SHORT).show();
      } }, 5, 9, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

   // set the "test " spannable.
      span.setSpan(cs, 0, 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

   // set the " span" spannable
      span.setSpan(cs, 6, span.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

textView.setText(span);
textView.setMovementMethod(LinkMovementMethod.getInstance());

Hope this will help you.

Hiren Patel
  • 52,124
  • 21
  • 173
  • 151