实现TextView中link的点击效果
朋友们,你们在TextView处理link的时候是不是一直被苦逼的android默认的方式困扰?每次点击link的时候,点击效果是整个textview来响应。非常烂吧?原因就不多赘述了。
那么以下这个控件就适合你了。 gitbub的链接:https://github.com/zhangjizxc/LinkClickTextView
好用的话。帮忙点个赞。
package com.zhang.linkclick; import com.test.zhang.R; import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Handler;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.TextView; /**
*
* @author zhangji
*
*/
public class LinkClickTextView extends TextView { private static final String TAG = "LinkClickTextView";
private ClickableSpan mSelectedLink;
private boolean mHasPerformedLongPress;
private CheckForLongPress mPendingCheckForLongPress;
private ForegroundColorSpan mForegroundColorSpan;
private UnsetLinkPressedState mUnsetLinkPressedState; public LinkClickTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
} public LinkClickTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setLinksClickable(false);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LinkClickTextView, defStyle, 0);
ColorStateList titleColor = a.getColorStateList(R.styleable.LinkClickTextView_textColorLinkClick);
if (titleColor != null) {
mForegroundColorSpan =new ForegroundColorSpan(titleColor.getColorForState(EMPTY_STATE_SET, Color.RED));
}
} @Override
public boolean onTouchEvent(MotionEvent event) {
boolean handled = handledLinkTouch(event); if (handled) {
return true;
} else {
return super.onTouchEvent(event);
}
} @Override
public void cancelLongPress() {
removeLongPressCallback();
super.cancelLongPress();
} @Override
protected void onDetachedFromWindow() {
removeLongPressCallback();
super.onDetachedFromWindow();
} private boolean handledLinkTouch(MotionEvent event) { CharSequence text = getText();
int pointCount = event.getPointerCount();
if (!(text instanceof Spannable) || pointCount > 1) {
return false;
}
int action = event.getAction();
Spannable buffer = (Spannable) text;
switch (action) {
case MotionEvent.ACTION_DOWN:
int x = (int) event.getX();
int y = (int) event.getY(); x -= this.getTotalPaddingLeft();
y -= this.getTotalPaddingTop(); x += this.getScrollX();
y += this.getScrollY(); Layout layout = this.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x); ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
checkForLongClick(0);
mSelectedLink = link[0];
setLinkPressed(true);
return true;
} else {
mSelectedLink = null;
}
break;
case MotionEvent.ACTION_MOVE:
if (mSelectedLink != null) {
return true;
}
break;
case MotionEvent.ACTION_UP:
if (mSelectedLink != null) {
if (!mHasPerformedLongPress) {
// This is a tap, so remove the longpress check
removeLongPressCallback();
mSelectedLink.onClick(this);
}
if (mUnsetLinkPressedState == null) {
mUnsetLinkPressedState = new UnsetLinkPressedState();
}
postDelayed(mUnsetLinkPressedState,
ViewConfiguration.getPressedStateDuration());
mSelectedLink = null;
return true;
}
break;
case MotionEvent.ACTION_CANCEL:
removeLongPressCallback();
break;
default:
break;
}
return false;
} private void checkForLongClick(int delayOffset) {
if (isLongClickable()) {
mHasPerformedLongPress = false; if (mPendingCheckForLongPress == null) {
mPendingCheckForLongPress = new CheckForLongPress();
}
mPendingCheckForLongPress.rememberWindowAttachCount();
postDelayed(mPendingCheckForLongPress,
ViewConfiguration.getLongPressTimeout() - delayOffset);
}
} private void removeLongPressCallback() {
if (mPendingCheckForLongPress != null) {
removeCallbacks(mPendingCheckForLongPress);
}
} class CheckForLongPress implements Runnable { private int mOriginalWindowAttachCount; public void run() {
if (mOriginalWindowAttachCount == getWindowAttachCount()) {
if (performLongClick()) {
mHasPerformedLongPress = true;
}
}
} public void rememberWindowAttachCount() {
mOriginalWindowAttachCount = getWindowAttachCount();
}
} private void setLinkPressed(boolean pressed) {
if (!(getText() instanceof Spannable) || mForegroundColorSpan == null) {
return;
}
Spannable buffer = (Spannable) getText();
if (buffer == null) {
return;
}
if (pressed) {
buffer.setSpan(mForegroundColorSpan, buffer.getSpanStart(mSelectedLink),
buffer.getSpanEnd(mSelectedLink), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
buffer.removeSpan(mForegroundColorSpan);
}
} private final class UnsetLinkPressedState implements Runnable {
public void run() {
setLinkPressed(false);
}
}
}
实现TextView中link的点击效果的更多相关文章
- css上传图片中等待不可点击效果
<!DOCTYPE html> <html> <head> <title>上传中</title> <style type=" ...
- 让低版本的 Android 项目显示出 Material 风格的点击效果
每天都被不同的需求纠缠的生活是幸福而又不幸的,这不我们家亲爱的设计师们又让我们在低版本的 Android 平台上实现一下类似于 Material Design 的点击效果. 虽然大家都知道 Mater ...
- TextView中超链接拦截
TextView中的超链接点击时,其实是通过Intent方式的,因此会调用Activity中的startActivity(Intent intent)方法,所以可在此方法中做些简单的拦截操作 例如拦截 ...
- android selector设置button点击效果(具体)以及常见问题
button的点击效果学习起来其实比較easy,此点对开发人员来说也是使用的比較频繁的一个知识点,与它相关的还有编辑框的获取焦点时改变背景颜色.选择button选择时改变字体颜色等等.这些其实都是用到 ...
- 自定义可点击的ImageSpan并在TextView中内置“View“
有的时候可能想在TextView中添加一些图片,比如下图,发短信输入联系人时,要把联系人号码换成一个图片,但这个图片无法用固定的某张图,而是根据内容进行定制的,这更像一个view. 当然,如果你不是v ...
- AndroidRichText 让Textview轻松的支持富文本(图像ImageSpan、点击效果等等类似QQ微信聊天)
代码地址:https://github.com/Luction/AndroidRichText AndroidRichText帮助实现像QQ,微信一样的,一个TextView里既有文字又有表情又有图片 ...
- Android TextView中实现点击文本超链接(无下划线)的封装类
android中有的时候须要在TextView上设置一些超链接,点击这些超链接时进行一些操作.比如新浪微博上的一些keyword,点击时会跳转到对应的页面. 怎样实现我们就直接看源代码吧. /** * ...
- Android TextView点击效果
在Android开发中,我们有时候需要单独的点击某一段文本,如图所示: 如上图,我们要求点击新用户注册这个TextView,为了有更好的用户体验,我们肯定要设置该TextView的点击效果.下面介绍如 ...
- robot framework程序运行过程中,遇到点击事件之后,未出现点击之后的效果(求解)
1.click Element操作,在实际过程中偶然会出现,日志显示已点击成功,但是实际自动化页面,没有点击成功之后的操作 现象: 现象描述:程序执行到点击侧边栏的[人员信息]之后,日志显示已经点击成 ...
随机推荐
- 编绎调试HotSpot JVM及在Eclipse里调试HotSpot一些步骤
编绎整个OpenJDK要很久,而且有很多东西是不需要的.研究HotSpot的话,其实只要下HotSpot部分的代码就可以了. 下面简单记录下编绎调试HotSpot一些步骤. 一.编绎 进入hotsop ...
- AtCoder Petrozavodsk Contest 001
第一场apc,5H的持久战,我当然水几个题就睡了 A - Two Integers Time limit : 2sec / Memory limit : 256MB Score : 100 point ...
- iis上的反向代理
阅读文章: IIS上的反向代理 ARR(Application Request Routing)
- tomcat(不仅仅是tomcat)通过熵池解决在linux启动应用慢
tomcat启动过程中报错 -Jul- ::] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web applica ...
- 一步一步,完成sparkMLlib对日志文件的处理(1)
https://blog.csdn.net/u012834750/article/details/81014997 初学第一天,当然是完成helloWorld啦,有点艰难,2个小时,在idea, ...
- poj 4001 To Miss Our Children Time
To Miss Our Children Time Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Jav ...
- freemarker实现自定义指令和自定义函数
自定义指令: 1.指令在前台实现 <#macro name param1,param2,param3...paramN> </#macro> 2.指令在后台实现 1.实现Tem ...
- 超级钢琴 BZOJ 2006
超级钢琴 [问题描述] 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度 ...
- ROS学习网址【原创】
ROS学习网址 http://www.ros.org/ http://www.ros.org/news/book/ http://wiki.ros.org/ http://blog.exbot.net ...
- hdu 1588(矩阵好题+递归求解等比数列)
Gauss Fibonacci Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...