单击时更改 TextView 的背景颜色
Changing background color of a TextView when clicked
在某些应用程序中,例如 Plaid 甚至 Chrome 浏览器,文本的某些部分带有下划线以表明它们是可点击的 link浏览器 window 或新标签页。单击这些 link 时,整个文本的背景颜色变为下划线颜色。我试过查看 Plaid 的来源来复制这种效果,但没有成功。我想要完成的是这个效果:
在 res/drawable/my_background 中创建一个 XML 资源文件。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" />
我认为这部分代码产生了这种效果:
其实是基于这个问题:
Change the text color of a single ClickableSpan when pressed without affecting other ClickableSpans in the same 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;
}
}
在某些应用程序中,例如 Plaid 甚至 Chrome 浏览器,文本的某些部分带有下划线以表明它们是可点击的 link浏览器 window 或新标签页。单击这些 link 时,整个文本的背景颜色变为下划线颜色。我试过查看 Plaid 的来源来复制这种效果,但没有成功。我想要完成的是这个效果:
在 res/drawable/my_background 中创建一个 XML 资源文件。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" />
我认为这部分代码产生了这种效果:
其实是基于这个问题:
Change the text color of a single ClickableSpan when pressed without affecting other ClickableSpans in the same 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;
}
}