您的位置:首页 > 其它

textview文本片段点击事件与textview点击事件冲突执行两次(最终解决办法)

2017-07-11 14:53 501 查看
开发项目中遇到 需要在一个textview中能够点击@好友跳转 用的是下面的方法:
SpannableString nameSpan = new SpannableString(name);
nameSpan.setSpan(new ClickableSpan() {
@Override
public void onClick(View widget) {
// TODO Auto-generated method stub

}
}, 0, nameSpan.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

但是写好后发现 再点击“@好友“之后会同时执行上面的ClickableSpan的onClick方法和textview的监听器onClick方法。

百思不得其解,在网上搜了一下午都找不到满意的答案,看来都是你抄我的我抄你的,抄来抄去,看着都生气;

最后还是国外某个网站上搜到的,虽然英文不咋好,还是跌跌撞撞搜到了答案;o(╯□╰)o (不说废话了,直接上答案):

import android.text.Layout;
import android.text.NoCopySpan;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.MovementMethod;
import android.text.method.ScrollingMovementMethod;
import android.text.style.ClickableSpan;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;

public class
CustomLinkMovementMethod
extends ScrollingMovementMethod
{
private static final int CLICK = 1;
private static final int UP = 2;
private static final int DOWN = 3;

public abstract interface TextClickedListener {
public abstract void onTextClicked();
}
TextClickedListener listener = null;
public void setOnTextClickListener(TextClickedListener listen){
listener = listen;
}
@Override
public boolean onKeyDown(TextView widget, Spannable buffer,
int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
if (event.getRepeatCount() == 0) {
if (action(CLICK, widget, buffer)) {
return true;
}
}
}

return super.onKeyDown(widget, buffer, keyCode, event);
}

@Override
protected boolean up(TextView widget, Spannable buffer) {
if (action(UP, widget, buffer)) {
return true;
}

return super.up(widget, buffer);
}

@Override
protected boolean down(TextView widget, Spannable buffer) {
if (action(DOWN, widget, buffer)) {
return true;
}

return super.down(widget, buffer);
}

@Override
protected boolean left(TextView widget, Spannable buffer) {
if (action(UP, widget, buffer)) {
return true;
}

return super.left(widget, buffer);
}

@Override
protected boolean right(TextView widget, Spannable buffer) {
if (action(DOWN, widget, buffer)) {
return true;
}

return super.right(widget, buffer);
}

private boolean action(int what, TextView widget, Spannable buffer) {
boolean handled = false;

Layout layout = widget.getLayout();

int padding = widget.getTotalPaddingTop() +
widget.getTotalPaddingBottom();
int areatop = widget.getScrollY();
int areabot = areatop + widget.getHeight() - padding;

int linetop = layout.getLineForVertical(areatop);
int linebot = layout.getLineForVertical(areabot);

int first = layout.getLineStart(linetop);
int last = layout.getLineEnd(linebot);

ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class);

int a = Selection.getSelectionStart(buffer);
int b = Selection.getSelectionEnd(buffer);

int selStart = Math.min(a, b);
int selEnd = Math.max(a, b);

if (selStart < 0) {
if (buffer.getSpanStart(FROM_BELOW) >= 0) {
selStart = selEnd = buffer.length();
}
}

if (selStart > last)
selStart = selEnd = Integer.MAX_VALUE;
if (selEnd < first)
selStart = selEnd = -1;

switch (what) {
case CLICK:
if (selStart == selEnd) {
return false;
}

ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class);

if (link.length != 1)
return false;

link[0].onClick(widget);
break;

case UP:
int beststart, bestend;

beststart = -1;
bestend = -1;

for (int i = 0; i < candidates.length; i++) {
int end = buffer.getSpanEnd(candidates[i]);

if (end < selEnd || selStart == selEnd) {
if (end > bestend) {
beststart = buffer.getSpanStart(candidates[i]);
bestend = end;
}
}
}

if (beststart >= 0) {
Selection.setSelection(buffer, bestend, beststart);
return true;
}

break;

case DOWN:
beststart = Integer.MAX_VALUE;
bestend = Integer.MAX_VALUE;

for (int i = 0; i < candidates.length; i++) {
int start = buffer.getSpanStart(candidates[i]);

if (start > selStart || selStart == selEnd) {
if (start < beststart) {
beststart = start;
bestend = buffer.getSpanEnd(candidates[i]);
}
}
}

if (bestend < Integer.MAX_VALUE) {
Selection.setSelection(buffer, beststart, bestend);
return true;
}

break;
}

return false;
}

public boolean onKeyUp(TextView widget, Spannable buffer,
int keyCode, KeyEvent event) {
return false;
}

@Override
public boolean onTouchEvent(TextView widget, Spannable buffer,
MotionEvent event) {
int action = event.getAction();

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 if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
}

return true;
} else {
Selection.removeSelection(buffer);

if (action == MotionEvent.ACTION_UP) {
if(listener != null)
listener.onTextClicked();
}
}
}

return super.onTouchEvent(widget, buffer, event);
}

public void initialize(TextView widget, Spannable text) {
Selection.removeSelection(text);
text.removeSpan(FROM_BELOW);
}

public void onTakeFocus(TextView view, Spannable text, int dir) {
Selection.removeSelection(text);

if ((dir & View.FOCUS_BACKWARD) != 0) {
text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT);
} else {
text.removeSpan(FROM_BELOW);
}
}

public static MovementMethod getInstance() {
if (sInstance == null)
sInstance = new CustomLinkMovementMethod();

return sInstance;
}

private static CustomLinkMovementMethod sInstance;
private static Object FROM_BELOW = new NoCopySpan.Concrete();
}

在你的代码上加上:[/code]
CustomLinkMovementMethod link = (CustomLinkMovementMethod)CustomLinkMovementMethod.getInstance();
//textview默认的点击事件可以写在这里,也可以另写(写在这里貌似会有点混乱)
link.setOnTextClickListener(new CustomLinkMovementMethod.TextClickedListener() {
@Override
public void onTextClicked() {
Toast.makeText(UserProfileActivity.this, "text Pressed", Toast.LENGTH_LONG).show();

}
});
YOUR_TEXTVIEW.setMovementMethod(link);
1
2
3
4
5
6
7
8
9
10
只需要上面这一个就可以了,下面两个也不用加了:

YOUR_TEXTVIEW.setMovementMethod(ScrollingMovementMethod.getInstance());//滑动
YOUR_TEXTVIEW.setMovementMethod(LinkMovementMethod.getInstance());//开始响应点击事件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐