美文网首页
2019-05-22 解决Span点击变色和点击冲突

2019-05-22 解决Span点击变色和点击冲突

作者: 兣甅 | 来源:发表于2019-05-22 17:47 被阅读0次

使用三部曲

1. 
clickPreventableTextView.highlightColor = Color.TRANSPARENT
2. 
clickPreventableTextView.movementMethod = LinkTouchMovementMethod()
3. 
private val mColorAtNormal = Color.parseColor("#3DC27C")
private val mColorAtPressed = Color.parseColor("#3DC27C")
clickPreventableTextView.text = SpannableString("@${user.name}")
    stringClick.setSpan(
      object : TouchableSpan(mColorAtNormal, mColorAtPressed, Color.TRANSPARENT) {
        override fun onClick(widget: View) {
          if (widget is ClickPreventableTextView) {
            widget.preventNextClick()
          }
          context.toast("打开用户:${user.name}")
        }
      }, 0, stringClick.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
    )
import android.content.Context;
import android.support.v7.widget.AppCompatTextView;
import android.text.Spannable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * description: 解决有SpanClick点击事件和TextView点击事件同时出发的TextView.
 *
 * @date 2018/8/13 11:54.
 * @author: xxx.
 */
public class ClickPreventableTextView extends AppCompatTextView implements View.OnClickListener {
  private boolean preventClick;
  private View.OnClickListener clickListener;

  public ClickPreventableTextView(Context context) {
    super(context);
    init();
  }

  public ClickPreventableTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
  }

  public ClickPreventableTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
  }

  private void init() {
    setHighlightColor(Color.TRANSPARENT);
    setMovementMethod(new LinkTouchMovementMethod());
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    if (getMovementMethod() != null) {
      getMovementMethod().onTouchEvent(this, (Spannable) getText(), event);
    }
    return super.onTouchEvent(event);
  }

  /**
   * ClickSpan点击事件出发后调用
   */
  public void preventNextClick() {
    preventClick = true;
  }

  @Override
  public void setOnClickListener(View.OnClickListener listener) {
    this.clickListener = listener;
    super.setOnClickListener(this);
  }

  @Override
  public void onClick(View v) {
    if (preventClick) {
      preventClick = false;
    } else if (clickListener != null) {
      clickListener.onClick(v);
    }
  }
}


import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.view.MotionEvent;
import android.widget.TextView;

/**
 * 用于点击ClickableSpan时多个按钮分别变色
 * Author:caiyoufei
 * Date:2016/6/1
 * Time:14:09
 */
public class LinkTouchMovementMethod extends LinkMovementMethod {
  private TouchableSpan mPressedSpan;

  @Override
  public boolean onTouchEvent(TextView textView, Spannable spannable, MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
      mPressedSpan = getPressedSpan(textView, spannable, event);
      if (mPressedSpan != null) {
        mPressedSpan.setPressed(true);
        Selection.setSelection(spannable, spannable.getSpanStart(mPressedSpan),
            spannable.getSpanEnd(mPressedSpan));
      }
    } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
      TouchableSpan touchedSpan = getPressedSpan(textView, spannable, event);
      if (mPressedSpan != null && touchedSpan != mPressedSpan) {
        mPressedSpan.setPressed(false);
        mPressedSpan = null;
        Selection.removeSelection(spannable);
      }
    } else {
      if (mPressedSpan != null) {
        mPressedSpan.setPressed(false);
        super.onTouchEvent(textView, spannable, event);
      }
      mPressedSpan = null;
      Selection.removeSelection(spannable);
    }
    return true;
  }

  private TouchableSpan getPressedSpan(TextView textView, Spannable spannable, MotionEvent event) {

    int x = (int) event.getX();
    int y = (int) event.getY();

    x -= textView.getTotalPaddingLeft();
    y -= textView.getTotalPaddingTop();

    x += textView.getScrollX();
    y += textView.getScrollY();

    Layout layout = textView.getLayout();
    int line = layout.getLineForVertical(y);
    int off = layout.getOffsetForHorizontal(line, x);

    TouchableSpan[] link = spannable.getSpans(off, off, TouchableSpan.class);
    TouchableSpan touchedSpan = null;
    if (link.length > 0) {
      touchedSpan = link[0];
    }
    return touchedSpan;
  }
}

import android.graphics.Color;
import android.text.TextPaint;
import android.text.style.ClickableSpan;

/**
 * 为多个TouchableSpan分别添加点击变色
 * Author:caiyoufei
 * Date:2016/6/1
 * Time:14:06
 */
public abstract class TouchableSpan extends ClickableSpan {
  private boolean mIsPressed;
  private boolean mIsShowUnderLine;
  private int mPressedBackgroundColor;
  private int mNormalTextColor;
  private int mPressedTextColor;

  public TouchableSpan(int normalTextColor, int pressedTextColor, int pressedBackgroundColor) {
    mNormalTextColor = normalTextColor;
    mPressedTextColor = pressedTextColor;
    mPressedBackgroundColor = pressedBackgroundColor;
  }

  public TouchableSpan(int normalTextColor, int pressedTextColor, int pressedBackgroundColor,
      boolean isShowUnderLine) {
    mNormalTextColor = normalTextColor;
    mPressedTextColor = pressedTextColor;
    mPressedBackgroundColor = pressedBackgroundColor;
    mIsShowUnderLine = isShowUnderLine;
  }

  public void setPressed(boolean isSelected) {
    mIsPressed = isSelected;
  }

  @Override
  public void updateDrawState(TextPaint ds) {
    super.updateDrawState(ds);
    ds.setColor(mIsPressed ? mPressedTextColor : mNormalTextColor);
    ds.bgColor = mIsPressed ? mPressedBackgroundColor : Color.TRANSPARENT;
    ds.setUnderlineText(mIsShowUnderLine);
  }
}

相关文章

网友评论

      本文标题:2019-05-22 解决Span点击变色和点击冲突

      本文链接:https://www.haomeiwen.com/subject/dbauzqtx.html