@SuppressWarnings("NullableProblems") @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); int x = (int) event.getX(); int y = (int) event.getY(); x += getScrollX(); y += getScrollY(); boolean retValue = false; switch (action) { case MotionEvent.ACTION_DOWN: retValue = selectBubble(x, y); break; case MotionEvent.ACTION_MOVE: if (selectedSpan != null) { selectedSpan.setPressed(spanContains(selectedSpan, x, y), (Spannable) layout().getText()); retValue = true; } break; case MotionEvent.ACTION_UP: if (listener != null && selectedSpan != null && spanContains(selectedSpan, x, y)) { listener.onBubbleClicked(this, selectedSpan); } case MotionEvent.ACTION_CANCEL: if (selectedSpan != null) { retValue = true; if (-1 != ((Spannable) truncatedLayout.getText()).getSpanEnd(selectedSpan)) { selectedSpan.setPressed(false, (Spannable) truncatedLayout.getText()); } if (-1 != ((Spannable) expandedLayout.getText()).getSpanEnd(selectedSpan)) { selectedSpan.setPressed(false, (Spannable) expandedLayout.getText()); } } selectedSpan = null; break; default: break; } invalidate(); return retValue; }
private void build(int width) { positions.clear(); width = width - getPaddingLeft() - getPaddingRight(); if (width <= 0 || TextUtils.isEmpty(text)) { truncatedLayout = expandedLayout = null; return; } for (BubbleSpan span : spans) { span.resetWidth(width); } try { truncatedLayout = expandedLayout = new StaticLayout( text, textPaint, width, Layout.Alignment.ALIGN_NORMAL, lineSpacing, 1, false); if (maxLines > 0 && truncatedLayout.getLineCount() > maxLines) { int lineEnd = truncatedLayout.getLineEnd(maxLines - 1); int offset = -1; StaticLayout sl = new StaticLayout( moreText, textPaint, width, Layout.Alignment.ALIGN_NORMAL, lineSpacing, 1, false); sl.getWidth(); while (truncatedLayout.getLineCount() > maxLines && lineEnd > 0) { if (offset == -1 && truncatedLayout.getLineWidth(maxLines - 1) + sl.getLineWidth(0) > width) { offset = truncatedLayout.getOffsetForHorizontal(maxLines - 1, width - sl.getLineWidth(0)); lineEnd = offset; } else if (offset > 0) { lineEnd--; } SpannableStringBuilder textTruncated = new SpannableStringBuilder(text.subSequence(0, lineEnd)); textTruncated.append(moreText); truncatedLayout = new StaticLayout( textTruncated, textPaint, width, Layout.Alignment.ALIGN_NORMAL, lineSpacing, 1, false); } } } catch (java.lang.ArrayIndexOutOfBoundsException e) { return; } if (truncated) { recomputeSpans((Spannable) truncatedLayout.getText()); } else { recomputeSpans((Spannable) expandedLayout.getText()); } for (BubbleSpan span : spans) { positions.put(span, span.rect(this)); } }