Changing the background color of a TextView when clicked

In some applications, such as Plaid or even in the Chrome browser, some parts of the text are underlined to indicate that it is an interactive link that will open a browser window or a new tab. When these links are clicked, the entire background color of the text changes to the entire underline color. I tried to look at the source of the Plade to reproduce this effect without success. I am trying to fulfill this effect:

enter image description here

+4
source share
2 answers

I think this part of the code creates this effect:

https://github.com/nickbutcher/plaid/blob/61d59644d5ae9e373f93cef10e0438c50e2eea6d/app/src/main/java/io/plaidapp/util/LinkTouchMovementMethod.java

:

ClickableSpan , ClickableSpans TextView

public class LinkTouchMovementMethod extends LinkMovementMethod {


private static LinkTouchMovementMethod instance;
private TouchableUrlSpan pressedSpan;

public static MovementMethod getInstance() {
    if (instance == null)
        instance = new LinkTouchMovementMethod();

    return instance;
}

@Override
public boolean onTouchEvent(TextView textView, Spannable spannable, MotionEvent event) {
    boolean handled = false;
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        pressedSpan = getPressedSpan(textView, spannable, event);
        if (pressedSpan != null) {
            pressedSpan.setPressed(true);
            Selection.setSelection(spannable, spannable.getSpanStart(pressedSpan),
                    spannable.getSpanEnd(pressedSpan));
            handled = true;
        }
    } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
        TouchableUrlSpan touchedSpan = getPressedSpan(textView, spannable, event);
        if (pressedSpan != null && touchedSpan != pressedSpan) {
            pressedSpan.setPressed(false);
            pressedSpan = null;
            Selection.removeSelection(spannable);
        }
    } else {
        if (pressedSpan != null) {
            pressedSpan.setPressed(false);
            super.onTouchEvent(textView, spannable, event);
            handled = true;
        }
        pressedSpan = null;
        Selection.removeSelection(spannable);
    }
    return handled;
}

private TouchableUrlSpan getPressedSpan(TextView textView, Spannable spannable, MotionEvent
        event) {

    int x = (int) event.getX();
    int y = (int) event.getY();

    x -= textView.getTotalPaddingLeft();
    y -= textView.getTotalPaddingTop();

    x += textView.getScrollX();
    y += textView.getScrollY();

    Layout layout = textView.getLayout();
    int line = layout.getLineForVertical(y);
    int off = layout.getOffsetForHorizontal(line, x);

    TouchableUrlSpan[] link = spannable.getSpans(off, off, TouchableUrlSpan.class);
    TouchableUrlSpan touchedSpan = null;
    if (link.length > 0) {
        touchedSpan = link[0];
    }
    return touchedSpan;
}

}

+2

XML res/drawable/my_background.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
    <shape>
        <solid android:color="#343434" />
    </shape>
</item>
</selector>

TextView ,

  <TextView
    android:id="@+id/tvMytv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/my_background" />
+2

Source: https://habr.com/ru/post/1614970/


All Articles