实现TextView中link的点击效果
2014-08-01 17:45
549 查看
朋友们,你们在TextView处理link的时候是不是一直被苦逼的android默认的方式困扰?每次点击link的时候,点击效果是整个textview来响应。很烂吧?原因就不多赘述了。
那么下面这个控件就适合你了。 gitbub的链接:https://github.com/zhangjizxc/LinkClickTextView
好用的话,帮忙点个赞。
那么下面这个控件就适合你了。 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的点击效果
- 怎样实现textview里显示的缩略图,点击查看大图的效果
- TextView SpannableString 使用之实现可点击超链接效果
- Android之实现TextView控件圆角以及Button点击、焦点效果
- TextView属性android:ellipsize实现跑马灯效果,TextView内容过长加省略号,点击显示全部内容
- Android TextView实现点击展开动画效果
- TextView实现超链接并自定义点击效果
- 用TextView实现button点击效果
- Android实现带动画效果的可点击展开TextView
- ios-textView实现点击相应的字符出现背景效果
- textview中点击效果实现,比如点击textview中实现图片和文字的颜色变化(类似于button)
- android 实现textview部分文字点击效果,类似于微博的话题丶用户
- textview添加selector实现button的点击效果
- [Android] ImageButton | Button | TextView 点击和触摸效果实现
- android TextView 实现自定义文字点击效果
- android中TextView的文字实现动态效果,走马灯效果,闪烁效果
- Android TextView实现跑马灯效果
- ListView 中的TextView实现跑马灯效果
- Android TextView中链接(link)点击事件的截取
- GoogleMap_IOS MKMapView如何实现不点击大头针,就可以出现calloutView效果