实现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操作,在实际过程中偶然会出现,日志显示已点击成功,但是实际自动化页面,没有点击成功之后的操作 现象: 现象描述:程序执行到点击侧边栏的[人员信息]之后,日志显示已经点击成 ...
随机推荐
- Numpy ndarray 的高级索引存在 "bug" ?
Numpy ndarray 高级索引 "bug" ? 话说一天,搞事情,代码如下 import numpy as np tmp = [1, 2, 3, 4] * 2 a, b = ...
- Leetcode 475.供暖气
供暖气 冬季已经来临. 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖. 现在,给出位于一条水平线上的房屋和供暖器的位置,找到可以覆盖所有房屋的最小加热半径. 所以,你的输入将会是房屋和供暖器 ...
- 【bzoj1778】[Usaco2010 Hol]Dotp 驱逐猪猡 矩阵乘法+概率dp+高斯消元
题目描述 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300)一共N个猪城.这些城市由M (1 <= M <= 44,850)条由两 ...
- LibreOJ2042 - 「CQOI2016」不同的最小割
Portal Description 给出一个给出一个\(n(n\leq850)\)个点\(m(m\leq8500)\)条边的无向图.定义\(cut(s,t)\)等于\(s,t\)的最小割的容量,求在 ...
- 兼容ie8 rgba()写法
background: rgba(255,255,255,.1); filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#1 ...
- MongoDb C# 驱动操作示例
c#操作mongo数据库 驱动采用http://www.oschina.net/p/mongo-csharp-driver C#驱动的基本数据库连接,增删改查操作 //定义对象 public clas ...
- 网络流24题-最长k可重线段集问题
最长k可重线段集问题 时空限制1000ms / 128MB 题目描述 给定平面 x−O−y 上 n 个开线段组成的集合 I,和一个正整数 k .试设计一个算法,从开线段集合 I 中选取出开线段集合 S ...
- 【CF1017A】The Rank(签到)
题意:给定n个人的4门课成绩,排名按总分,保证总分互不相同,求1号名次 n<=1e3,a[i],b[i],c[i],d[i]<=1e2 思路: #include<cstdio> ...
- 浅谈MVP设计模式
最近公司在做一个医疗项目,使用WinForm界面作为客户端交互界面.在整个客户端解决方案中.使用了MVP模式实现.由于之前没有接触过该设计模式,所以在项目完成到某个阶段时,将使用MVP的体会写在博客里 ...
- FFT题集
FFT学习参考这两篇博客,很详细,结合这看,互补. 博客一 博客二 很大一部分题目需要构造多项式相乘来进行计数问题. 1. HDU 1402 A * B Problem Plus 把A和B分别当作多项 ...