Android like person click event

Write picture description here

This is the effect we want to achieve. First of all, I want to introduce to you a project on github, https://github.com/nimengbo/TextViewSpanClickable
This project is to achieve the effect, here I just give an introduction to the use

/**
 * Created by Abner on 15/6/17.
 * QQ 230877476
 * Email [email protected]
 * 另一种,每项可点击
 */
@SuppressLint("AppCompatCustomView")
public class TopicTextView<T> extends TextView {
    private TopicTextView instance;
    private Context mContext;
    private StyleSpan boldSpan;
    private ForegroundColorSpan colorSpan;

    private TextTopicClickListener<T> textTopicClickListener;

    public void setTextTopicClickListener(TextTopicClickListener<T> textTopicClickListener) {
        this.textTopicClickListener = textTopicClickListener;
    }

    public TopicTextView(Context context) {
        super(context);
        mContext = context;
        initView();
    }

    public TopicTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        initView();
    }

    public TopicTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        initView();
    }

    private void initView() {
        instance = this;
        setMovementMethod(LinkMovementMethod.getInstance());
        setHighlightColor(getResources().getColor(R.color.transparent));
        boldSpan = new StyleSpan(Typeface.BOLD);
        colorSpan = new ForegroundColorSpan(getResources().getColor(R.color.gray_bbbbbb));
    }

    private TextBlankClickListener listener;

    public void setListener(TextBlankClickListener listener) {
        this.listener = listener;
    }

    private int mStart = -1;

    private int mEnd = -1;

    private android.os.Handler handler = new android.os.Handler();
    //计数
    private int leftTime;
    private Runnable countDownRunnable = new Runnable() {
        public void run() {
            leftTime--;
            if (leftTime == -1) {
                // 触发长按事件
                if (listener != null) {
                    listener.onLongClick(instance);
                }
            } else {
                //100毫秒执行一次 超过500毫秒就说明触发长按
                handler.postDelayed(this, 100);
            }
        }
    };
    private boolean isMove = false;
    private float lastX;
    private float lastY;
    private int originalStart = -1;
    private int originalEnd = -1;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean result = super.onTouchEvent(event);

        int action = event.getAction();

        int x = (int) event.getX();
        int y = (int) event.getY();
        if (action == MotionEvent.ACTION_DOWN) {
            lastX = event.getX();
            lastY = event.getY();
            isMove = false;
        } else if (action == MotionEvent.ACTION_MOVE) {
            float distanceX = Math.abs(lastX - event.getX());
            float distanceY = Math.abs(lastY - event.getY());
            if (distanceX > 1.5f || distanceY > 1.5f) {
                isMove = true;
            }
        }

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

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

        Layout layout = getLayout();
        int line = layout.getLineForVertical(y);
        int off = layout.getOffsetForHorizontal(line, x);
        CharSequence text = getText();
        if (TextUtils.isEmpty(text) || !(text instanceof Spannable)) {
            return result;
        }
        Spannable buffer = (Spannable) text;
        ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
        if (link.length != 0) {
            if (action == MotionEvent.ACTION_DOWN) {
                mStart = buffer.getSpanStart(link[0]);
                mEnd = buffer.getSpanEnd(link[0]);
                if (mStart >= 0 && mEnd >= mStart) {
                    buffer.setSpan(new BackgroundColorSpan(Color.GRAY), mStart, mEnd,
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
                if (mStart >= 0 && mEnd >= mStart) {
                    buffer.setSpan(new BackgroundColorSpan(Color.TRANSPARENT), mStart, mEnd,
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    mStart = -1;
                    mEnd = -1;
                }
            } else if (action == MotionEvent.ACTION_MOVE) {
                if (isMove) {
                    if (mStart >= 0 && mEnd >= mStart) {
                        buffer.setSpan(new BackgroundColorSpan(Color.TRANSPARENT), mStart, mEnd,
                                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                        mStart = -1;
                        mEnd = -1;
                    }
                }
            }
            return true;
        } else {

            if (mStart >= 0 && mEnd >= mStart) {
                buffer.setSpan(new BackgroundColorSpan(Color.TRANSPARENT), mStart, mEnd,
                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                mStart = -1;
                mEnd = -1;
            }
            if (action == MotionEvent.ACTION_DOWN) {
                setBackgroundColor(Color.GRAY);
                //开始计数
                leftTime = 5;
                handler.post(countDownRunnable);
                return true;
            } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
                setBackgroundColor(Color.TRANSPARENT);
                //如果没有调用长按 调用点击整个的监听
                if (leftTime > -1) {
                    leftTime = 10;
                    handler.removeCallbacks(countDownRunnable);//移除统计
                    if (listener != null && !isMove) {
                        listener.onBlankClick(this);
                    }
                }
            } else if (action == MotionEvent.ACTION_MOVE) {
                if (isMove) {
                    setBackgroundColor(Color.TRANSPARENT);
                }
            }
            Selection.removeSelection(buffer);
            return false;
        }
    }


    /**
     * 设置点赞的内容
     *
     * @param topics
     * @return
     */
    public void setTopics(List<LikeUserAppDto> topics) {


        setText("");
        int length = topics.size();
        //设置点赞人前边默认的蓝色空心的心形图片
        SpannableStringBuilder defaultStringBuilder = new SpannableStringBuilder("#");
        Drawable drawable = mContext.getResources().getDrawable(R.mipmap.blue_heart);
        drawable.setBounds(0, 5, 40, 40);
        HouseImageSpan imageSpan = new HouseImageSpan(drawable);
        defaultStringBuilder.setSpan(imageSpan, 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
        append(defaultStringBuilder);
        //展示个人头像图片,此处可以根据自己的需求进行改动
        for (int i = 0; i < length; i++) {
            String topic;
            if (i == length - 1) {
                topic = " " + topics.get(i).getNickname();
            } else {
                topic = " " + topics.get(i).getNickname() + " ";
            }
            Drawable drawable1 = mContext.getResources().getDrawable(R.mipmap.moren_head_2);
            drawable1.setBounds(15, 0, 63, 48);
            HouseImageSpan imageSpan1 = new HouseImageSpan(drawable1);
            final SpannableStringBuilder imgStringBuilder = new SpannableStringBuilder("#");
            imgStringBuilder.setSpan(imageSpan1, 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

            if (StringHelper.isNotEmpty(topics.get(i).getLogo())) {
                if (topics.get(i).getBitmap() != null) {
                    Bitmap bitmap = BitmapHelper.getImageSmall(topics.get(i).getBitmap(), 120, 120);
                    Bitmap bitmap2 = BitmapHelper.toRoundBitmap(bitmap);
                    //设置头像图片的显示位置
                    Drawable drawable2 = DrawableToUriHelper.getInstance().bitmapToDrawable(bitmap2);
                    drawable2.setBounds(15, 0, 63, 48);
                    HouseImageSpan imageSpan2 = new HouseImageSpan(drawable2);
                    imgStringBuilder.setSpan(imageSpan2, 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
                    append(imgStringBuilder);
                }
            }
            //设置点赞人员的昵称
            SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(topic);
            //富文本点击事件的Span
            TopicSpan topicSpan = new TopicSpan(topics.get(i), getResources(), textTopicClickListener);
            spannableStringBuilder.setSpan(topicSpan, 0, topic.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            append(spannableStringBuilder);
        }
    }
}

The HouseImageSpan mentioned in the code can be learned through https://blog.csdn.net/zhourui_1021/article/details/80996165 .
This is the custom TextView used to achieve this effect. I changed it to a generic form that can be passed to facilitate my own use. The TopicSpan code used is as follows

/**
 * Created by Abner on 15/6/17.
 * QQ 230877476
 * Email nimengbo@gmail.com
 */
public class TopicSpan<T> extends ClickableSpan {
    
    

    private T topic;
    private StyleSpan boldSpan;
    private Resources resources;
    private TextTopicClickListener<T> topicClickListener;


    public TopicSpan(T topic, Resources resources, TextTopicClickListener<T> listener) {
        this.topic = topic;
        this.resources = resources;
        topicClickListener = listener;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        super.updateDrawState(ds);
        ds.setUnderlineText(false);
        ds.setColor(resources.getColor(R.color.blue_1779ff));
    }

    @Override
    public void onClick(View widget) {
        if(topicClickListener != null){
            topicClickListener.onTopicClick(widget,topic);
        }
    }
}```

这个类的代码我也是传入了泛型,以供方便使用,TextTopicClickListener的代码如下所示::

/**
* Created by Abner on 15/6/17.
* QQ 230877476
* Email [email protected]
*/
public interface TextTopicClickListener< T > {

void onTopicClick(View view, T topic);

}

TextBlankClickListener 代码::
/**
* Created by Abner on 15/6/17.
* QQ 230877476
* Email [email protected]
*/
public interface TextBlankClickListener {

void onBlankClick(View view);

void onLongClick(View view);

}


这就是涉及到的代码,下面介绍使用方式:布局中的写法

<自己存放的位置.TopicTextView
android:id=”@+id/tv_community_like”
android:layout_width=”match_parent”
android:layout_height=”wrap_content”
android:layout_marginLeft=”@dimen/px_15”
android:layout_marginTop=”@dimen/px_5”
android:gravity=”center_vertical”
android:textColor=”@color/blue_1779ff”
android:textSize=”@dimen/px_24” />

tv_community_like.setTextTopicClickListener(new TextTopicClickListener() {
@Override
public void onTopicClick(View view, the form topic
you need ) { the logic you need
}
});
//Set the content displayed by the TextView, the setTopics method is in the custom TextView The method of setting content
tv_community_like.setTopics(item.getLikes());
"`

This is how the complete provision of the click event of the like person can be realized.

My technique is relatively poor, so I sorted out this function and hoped to help everyone, and secondly, it could help myself to use it more conveniently in the future. Welcome to leave a message and correct me.

Guess you like

Origin blog.csdn.net/zhourui_1021/article/details/81589376