自定义TextView
import android.content.Context;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.TextPaint;
import android.text.method.BaseMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
/**
* 文件名:TextViewFixTouchConsume
* 描 述:
* 作 者:
* 时 间:2021/3/31 11:13
*/
public class TextViewFixTouchConsume extends TextView {
public TextViewFixTouchConsume(Context context) {
super(context);
init();
}
public TextViewFixTouchConsume(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TextViewFixTouchConsume(
Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
setMovementMethod(ClickableMovementMethod.getInstance());
setFocusable(false);
setClickable(false);
setLongClickable(false);
try {
final Spannable spannable = (Spannable) getText();
final URLSpan[] urlSpans = spannable.getSpans(0, getText().length(), URLSpan.class);
if (urlSpans != null && urlSpans.length > 0) {
final SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(spannable);
for (URLSpan urlSpan : urlSpans) {
final String url = urlSpan.getURL();
spannableStringBuilder.setSpan(
// new URLSpan(url) {
new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
onLongClickListener.onClick(url);
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
}, spannable.getSpanStart(urlSpan), spannable.getSpanEnd(urlSpan),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
setText(spannableStringBuilder, TextView.BufferType.SPANNABLE);
}
} catch (Exception e) {
}
}
long downTime;
long moveTime;
long upTime;
public interface LongClickListener {
void longClick();
void onClick(String url);
}
LongClickListener onLongClickListener;
public void setOnLongClickListener(LongClickListener onLongClickListener) {
this.onLongClickListener = onLongClickListener;
}
boolean canLongClick;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
canLongClick = true;
downTime = System.currentTimeMillis();
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
moveTime = System.currentTimeMillis();
if (moveTime - downTime > 500 && canLongClick) {
canLongClick = false;
if (onLongClickListener != null)
onLongClickListener.longClick();
return false;
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
upTime = System.currentTimeMillis();
if (upTime - downTime < 250) {
if (onLongClickListener != null) {
onLongClickListener.onClick("empty url");
}
}
}
return super.onTouchEvent(event);
}
public static class ClickableMovementMethod extends BaseMovementMethod {
private static ClickableMovementMethod sInstance;
public static ClickableMovementMethod getInstance() {
if (sInstance == null) {
sInstance = new ClickableMovementMethod();
}
return sInstance;
}
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
int action = event.getActionMasked();
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length > 0) {
if (action == MotionEvent.ACTION_UP) {
link[0].onClick(widget);
} else {
Selection.setSelection(buffer, buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
}
return true;
} else {
Selection.removeSelection(buffer);
}
}
return false;
}
@Override
public void initialize(TextView widget, Spannable text) {
Selection.removeSelection(text);
}
}
}
xml布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00FF00"
android:padding="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.xxx.xxx.TextViewFixTouchConsume
android:id="@+id/textViewFixTouchConsume"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:autoLink="web"
android:background="#FFFF00"
android:text="测试测试测https://blog.csdn.net/qq_20330595试测试测试测试测试测试测试https://blog.csdn.net/qq_20330595测试测试测试测试测试" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
使用
textViewFixTouchConsume = findViewById(R.id.textViewFixTouchConsume);
container = findViewById(R.id.container);
container.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("xxx", "container Click");
}
});
container.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
Log.d("xxx", "container longClick");
//自己消费掉 不给点击事件
return true;
}
});
textViewFixTouchConsume.setOnLongClickListener(new TextViewFixTouchConsume.LongClickListener() {
@Override
public void longClick() {
Log.d("xxx", "longClick");
}
@Override
public void onClick(String url) {
Log.d("xxx", url);
}
});