实现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操作,在实际过程中偶然会出现,日志显示已点击成功,但是实际自动化页面,没有点击成功之后的操作 现象: 现象描述:程序执行到点击侧边栏的[人员信息]之后,日志显示已经点击成 ...
随机推荐
- 开发者工具删除元素Delete Element
开发者工具有个很好用的功能,通过删除元素,可以查看页面哪些元素比较特殊,同时也可以排除干扰.
- 2.启动ABP ASP.NET ZERO
1.使用VS2017打开项目,等待自动还原程序包结束 2.生成项目,确保项目全部生成成功 3.生成数据库 (1).将项目“MyCompanyName.AbpZeroTemplate.EntityFra ...
- 记账APP市场分析
文/欧小慧(简书作者)原文链接:http://www.jianshu.com/p/281fcdce3baa著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 一.市场环境 1.理财记账类用 ...
- HDU-3523 Image copy detection
题意难懂... 大意上说就是给m个排列P1,P2,P3...Pm,自己求个排列T使得T与Pi的各个数的绝对值差之和最小. 其实也就是二分最小匹配了.... #include <cstdlib&g ...
- HDU-1528/1962 Card Game Cheater
两组牌中两张牌相比能赢的就连,后求最大匹配. #include <cmath> #include <cstdlib> #include <cstdio> #incl ...
- SyntaxError: Non-UTF-8 code starting with '\xb4'...
需在开头指定编码格式,在在最开头添加如下代码: # -*- coding: gb2312 -*- 大功告成!
- javascript script load related【转】
先来看这行代码: <script src = "allMyClientSideCode.js"></script> 这有点儿……不怎么样.“这该放在哪儿?” ...
- Beyond compare vs kdiff3
這裡使用的 kdiff3 版本是 0.9.98 基於以下 三點,最終選擇了 beyond compare 1. kdiff3 不能刪檔案, 以下為例,不能刪1 2. kdiff3 ...
- AC日记——Count on a tree bzoj 2588
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
- jq 全选、反选、判断选中的条数
1.全选或全不选.当勾选全选按钮#selectAll旁边的复选框#all时,列表中的选项全部选中,反之取消勾选则列表中的选项全部为未选中状态. $("#all").click(fu ...