Java Code Examples for android.text.Layout#getLineStart()

The following examples show how to use android.text.Layout#getLineStart() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SpannableFoldTextView.java    From FoldText_Java with MIT License 6 votes vote down vote up
private void translateText(Layout layout, BufferType type) {
    if (layout.getLineCount() > mShowMaxLine) {
        SpannableStringBuilder span = new SpannableStringBuilder();
        int start = layout.getLineStart(mShowMaxLine - 1);
        int end = layout.getLineVisibleEnd(mShowMaxLine - 1);
        TextPaint paint = getPaint();
        StringBuilder builder = new StringBuilder(ELLIPSIZE_END);
        if (mTipGravity == END) {
            builder.append("  ").append(mFoldText);
            end -= paint.breakText(mOriginalText, start, end, false, paint.measureText(builder.toString()), null) + 1;
            float x = getWidth() - getPaddingLeft() - getPaddingRight() - getTextWidth(ELLIPSIZE_END.concat(mFoldText));
            while (layout.getPrimaryHorizontal(end - 1) + getTextWidth(mOriginalText.subSequence(end - 1, end).toString()) < x) {
                end++;
            }
            end -= 2;
        } else {
            end -= paint.breakText(mOriginalText, start, end, false, paint.measureText(builder.toString()), null) + 1;
        }
        CharSequence ellipsize = mOriginalText.subSequence(0, end);
        span.append(ellipsize);
        span.append(ELLIPSIZE_END);
        addTip(span, type);
    }
}
 
Example 2
Source File: UnderlinedTextView.java    From ankihelper with GNU General Public License v3.0 6 votes vote down vote up
@Override
protected void onDraw(Canvas canvas) {
    int count = getLineCount();

    final Layout layout = getLayout();
    float xStart, xStop, xDiff;
    int firstCharInLine, lastCharInLine;

    for (int i = 0; i < count; i++) {
        int baseline = getLineBounds(i, mRect);
        firstCharInLine = layout.getLineStart(i);
        lastCharInLine = layout.getLineEnd(i);

        xStart = layout.getPrimaryHorizontal(firstCharInLine);
        xDiff = layout.getPrimaryHorizontal(firstCharInLine + 1) - xStart;
        xStop = layout.getPrimaryHorizontal(lastCharInLine - 1) + xDiff;

        canvas.drawLine(xStart,
                baseline + mStrokeWidth,
                xStop,
                baseline + mStrokeWidth,
                mPaint);
    }

    super.onDraw(canvas);
}
 
Example 3
Source File: StrokeTextView.java    From customview-samples with Apache License 2.0 6 votes vote down vote up
private void drawStrokeBorder(Canvas canvas){
    Layout layout = getLayout();
    if(layout!=null){
        String text = getText().toString();
        int lineCount = getLineCount();
        //第一行文字顶部与控件顶部的距离
        int totalPaddingTop = getTotalPaddingTop();
        for (int i = 0; i < lineCount; i++) {
            int start = layout.getLineStart(i);
            int end = layout.getLineEnd(i);
            String rowStr = text.substring(start, end);

            float x = layout.getLineLeft(i)+getPaddingLeft();
            int y = totalPaddingTop + getBaseLine(i);

            Path textPath = new Path();
            getPaint().getTextPath(rowStr,0,rowStr.length(),x,y,textPath);
            mBorderPaint.setColor(mBorderColor);
            canvas.drawPath(textPath,mBorderPaint);
        }
    }
}
 
Example 4
Source File: JustifyTextView.java    From BigApp_Discuz_Android with Apache License 2.0 6 votes vote down vote up
@Override
protected void onDraw(Canvas canvas) {
    TextPaint paint = getPaint();
    paint.setColor(getCurrentTextColor());
    paint.drawableState = getDrawableState();
    mViewWidth = getMeasuredWidth();
    String text = (String) getText();
    mLineY = 0;
    mLineY += getTextSize();
    Layout layout = getLayout();
    for (int i = 0; i < layout.getLineCount(); i++) {
        int lineStart = layout.getLineStart(i);
        int lineEnd = layout.getLineEnd(i);
        String line = text.substring(lineStart, lineEnd);

        float width = StaticLayout.getDesiredWidth(text, lineStart, lineEnd, getPaint());
        if (needScale(line)) {
            drawScaledText(canvas, lineStart, line, width);
        } else {
            canvas.drawText(line, 0, mLineY, paint);
        }

        mLineY += getLineHeight();
    }
}
 
Example 5
Source File: ExpandTextView.java    From zone-sdk with MIT License 5 votes vote down vote up
/**
 * 得到最多行那个 最后一个字符的位置,与第一个位置 测出宽度 与 扩展字符 相加 如果大于行宽, 就把endPos--,知道小于。
 * 最后 截取字符  0-endPos 然后拼接  扩展字符 去显示即可!
 */
private void setExpand() {
    calExpand = true;
    Layout layout = getLayout();
    int endPos = layout.getLineEnd(maxLine - 1);
    int startPos = layout.getLineStart(maxLine - 1);
    TextPaint pt = getPaint();

    //如果宽度>测量宽度 就继续 --
    while (Layout.getDesiredWidth(getText(), startPos, endPos, pt) + Layout.getDesiredWidth(new SpannedString(EXPAND), pt) > layout.getWidth()
            && --endPos > startPos) {
    }
    SpannableStringBuilder nowSb = new SpannableStringBuilder(getText().subSequence(0, endPos)).append(EXPAND);
    setText(nowSb);
}
 
Example 6
Source File: LineUtils.java    From javaide with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Gets the lineInfo from the index of the letter in the text
 */
public static int getLineFromIndex(int index, int lineCount, Layout layout) {
    int line;
    int currentIndex = 0;

    for (line = 0; line < lineCount; line++) {
        currentIndex += layout.getLineEnd(line) - layout.getLineStart(line);
        if (currentIndex >= index) {
            break;
        }
    }
    return line;
}
 
Example 7
Source File: ContentTextViewJustified.java    From HeaderDialog with MIT License 5 votes vote down vote up
@Override
protected void onDraw(Canvas canvas) {
    TextPaint paint = getPaint();
    paint.setColor(getCurrentTextColor());
    paint.drawableState = getDrawableState();

    String text = getText().toString();

    float lineY = 0;
    lineY += getTextSize() * 1f;

    final Layout layout = getLayout();
    final float desiredLineWidth = getMeasuredWidth();

    for (int i = 0, lineCount = layout.getLineCount(); i < lineCount; i++) {
        int lineStart = layout.getLineStart(i);
        int lineEnd = layout.getLineEnd(i);
        String line = text.substring(lineStart, lineEnd);

        if (needScale(line) && i < lineCount - 1) {
            drawScaledText(line, canvas, lineY, desiredLineWidth, paint);
        } else {
            canvas.drawText(line, 0, lineY, paint);
        }

        lineY += getLineHeight();
    }
}
 
Example 8
Source File: SpanLineEditText.java    From customview-samples with Apache License 2.0 5 votes vote down vote up
private void refresh(){
    Layout layout = getLayout();
    if(layout != null){
        List<CustomSpanData> copySpanData = new ArrayList<>();
        copySpanData.addAll(mCustomTextSpanDataList);
        mCustomTextSpanDataList.clear();

        int lineCount = layout.getLineCount();
        String text = layout.getText().toString();
        int index = text.indexOf("\n");
        Log.d("hyh", "SpanLineEditText: refresh: index="+index);
        Log.d("hyh", "SpanLineEditText: refresh: text="+text+" ,lineCount="+lineCount);
        for (int i = 0; i < lineCount; i++) {
            int start = layout.getLineStart(i);
            int end = layout.getLineEnd(i);
            String rowStr = text.substring(start,end);
            Log.d("hyh", "SpanLineEditText: refresh: rowStr="+rowStr+" ,start="+start+" ,end="+end);
            CustomSpanData customTextSpanData = new CustomSpanData.Builder(text,start,end)
                .setTextSize(getRangeRandomInt())
                .setSpanType(TYPE_ABS_SIZE_SPAN)
                .build();
            mCustomTextSpanDataList.add(customTextSpanData);
        }
        if(!mLastText.equals(text)) {
            updateText(text);
        }
        mLastText = text;
    }
}
 
Example 9
Source File: AutoProcessor.java    From customview-samples with Apache License 2.0 5 votes vote down vote up
/**
 * 判断是否需要更新文本
 * @return
 */
private boolean isUpdateText(Layout layout,String text){
    boolean update = false;
    if(!mLastText.equals(text)) {
        update = true;
    }else{
        int lineCount = layout.getLineCount();
        int size = mLineDataList.size();
        if(lineCount != size){
            update = true;
        }else{
            for (int i = 0; i < lineCount; i++) {
                int start = layout.getLineStart(i);
                int end =layout.getLineEnd(i);
                String rowStr = text.substring(start, end);
                //去除掉换行符
                if(rowStr.contains(SYM_CHANGE_LINE)){
                    rowStr = rowStr.replace(SYM_CHANGE_LINE,"");
                }
                LineData lineData = mLineDataList.get(i);
                String lineText = lineData.getLineText();
                if (!rowStr.equals(lineText)) {
                    //原本的每行文字跟现在的每行文字不相同,说明排版变了,需要重新更新文本
                    update = true;
                    break;
                }
            }
        }
    }
    return  update;
}
 
Example 10
Source File: BaseKeyListener.java    From android_9.0.0_r45 with Apache License 2.0 5 votes vote down vote up
private boolean deleteLine(View view, Editable content) {
    if (view instanceof TextView) {
        final Layout layout = ((TextView) view).getLayout();
        if (layout != null) {
            final int line = layout.getLineForOffset(Selection.getSelectionStart(content));
            final int start = layout.getLineStart(line);
            final int end = layout.getLineEnd(line);
            if (end != start) {
                content.delete(start, end);
                return true;
            }
        }
    }
    return false;
}
 
Example 11
Source File: LineUtils.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
public static int getStartIndexAtLine(EditText editable, int line) {
    Layout layout = editable.getLayout();
    if (layout != null) {
        return layout.getLineStart(line);
    }
    return 0;
}
 
Example 12
Source File: LineUtils.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
/**
 * Gets the lineInfo from the index of the letter in the text
 */
public static int getLineFromIndex(int index, int lineCount, Layout layout) {
    int line;
    int currentIndex = 0;

    for (line = 0; line < lineCount; line++) {
        currentIndex += layout.getLineEnd(line) - layout.getLineStart(line);
        if (currentIndex >= index) {
            break;
        }
    }
    return line;
}
 
Example 13
Source File: HighlightEditor.java    From java-n-IDE-for-Android with Apache License 2.0 5 votes vote down vote up
/**
 * @param line   - current line
 * @param column - column of line
 * @return Position (in pixels) for edittext at line and column
 */
public Point getDebugPosition(int line, int column, int gravity) {
    Layout layout = getLayout();
    if (layout != null) {
        int pos = layout.getLineStart(line) + column;

        int baseline = layout.getLineBaseline(line);
        int ascent = layout.getLineAscent(line);

        int offsetHorizontal = (int) layout.getPrimaryHorizontal(pos) + mLinePadding; //x

        float y;
        int offsetVertical = 0;

        if (gravity == Gravity.BOTTOM) {
            y = baseline + ascent;
            if (verticalScroll != null) {
                offsetVertical = (int) ((y + mCharHeight) - verticalScroll.getScrollY());
            } else {
                offsetVertical = (int) ((y + mCharHeight) - getScrollY());
            }
            return new Point(offsetHorizontal, offsetVertical);
        } else if (gravity == Gravity.TOP) {
            y = layout.getLineTop(line);
            if (verticalScroll != null) {
                offsetVertical = (int) (y - verticalScroll.getScrollY());
            } else {
                offsetVertical = (int) (y - getScrollY());
            }
            return new Point(offsetHorizontal, offsetVertical);
        }

        return new Point(offsetHorizontal, offsetVertical);
    }
    return new Point();
}
 
Example 14
Source File: TextSpec.java    From litho with Apache License 2.0 5 votes vote down vote up
/**
 * Truncates text which is too long and appends the given custom ellipsis CharSequence to the end
 * of the visible text.
 *
 * @param text Text to truncate
 * @param customEllipsisText Text to append to the end to indicate truncation happened
 * @param newLayout A Layout object populated with measurement information for this text
 * @param ellipsizedLineNumber The line number within the text at which truncation occurs (i.e.
 *     the last visible line).
 * @return The provided text truncated in such a way that the 'customEllipsisText' can appear at
 *     the end.
 */
private static CharSequence truncateText(
    CharSequence text,
    CharSequence customEllipsisText,
    Layout newLayout,
    int ellipsizedLineNumber,
    float layoutWidth) {
  Rect bounds = new Rect();
  newLayout
      .getPaint()
      .getTextBounds(customEllipsisText.toString(), 0, customEllipsisText.length(), bounds);
  // Identify the X position at which to truncate the final line:
  // Note: The left position of the line is needed for the case of RTL text.
  final float ellipsisTarget =
      layoutWidth - bounds.width() + newLayout.getLineLeft(ellipsizedLineNumber);
  // Get character offset number corresponding to that X position:
  int ellipsisOffset = newLayout.getOffsetForHorizontal(ellipsizedLineNumber, ellipsisTarget);
  if (ellipsisOffset > 0) {
    // getOffsetForHorizontal returns the closest character, but we need to guarantee no
    // truncation, so subtract 1 from the result:
    ellipsisOffset -= 1;

    // Ensure that we haven't chosen an ellipsisOffset that's past the end of the ellipsis start.
    // This can occur in several cases, including when the width of the customEllipsisText is less
    // than the width of the default ellipsis character, and when in RTL mode and there is
    // whitespace to the left of the text. In these cases, getOffsetForHorizontal will return the
    // end of the string because our ellipsisTarget was in the middle of the ellipsis character.
    if (newLayout.getEllipsisCount(ellipsizedLineNumber) > 0) {
      final int ellipsisStart =
          newLayout.getLineStart(ellipsizedLineNumber)
              + newLayout.getEllipsisStart(ellipsizedLineNumber);
      if (ellipsisOffset > ellipsisStart) {
        ellipsisOffset = ellipsisStart;
      }
    }
    return TextUtils.concat(text.subSequence(0, ellipsisOffset), customEllipsisText);
  } else {
    return text;
  }
}
 
Example 15
Source File: JustifyTextView.java    From AlignTextView with Apache License 2.0 5 votes vote down vote up
@Override
protected void onDraw(Canvas canvas) {
	TextPaint paint = getPaint();
	paint.setColor(getCurrentTextColor());
	paint.drawableState = getDrawableState();
	mViewWidth = getMeasuredWidth();
	String text = getText().toString();
	mLineY = 0;
	mLineY += getTextSize();
	Layout layout = getLayout();

	// layout.getLayout()在4.4.3出现NullPointerException
	if (layout == null) {
		return;
	}

	Paint.FontMetrics fm = paint.getFontMetrics();

	int textHeight = (int) (Math.ceil(fm.descent - fm.ascent));
	textHeight = (int) (textHeight * layout.getSpacingMultiplier() + layout
			.getSpacingAdd());

	for (int i = 0; i < layout.getLineCount(); i++) {
		int lineStart = layout.getLineStart(i);
		int lineEnd = layout.getLineEnd(i);
		float width = StaticLayout.getDesiredWidth(text, lineStart,
				lineEnd, getPaint());
		String line = text.substring(lineStart, lineEnd);
		if (needScale(line)) {
			drawScaledText(canvas, lineStart, line, width);
		} else {
			canvas.drawText(line, 0, mLineY, paint);
		}
		mLineY += textHeight;
	}
}
 
Example 16
Source File: SelectableTextView.java    From AdvancedTextView with Apache License 2.0 5 votes vote down vote up
/**
 * 重绘文字,两端对齐
 *
 * @param canvas
 */
private void drawTextWithJustify(Canvas canvas) {
    // 文字画笔
    TextPaint textPaint = getPaint();
    textPaint.setColor(getCurrentTextColor());
    textPaint.drawableState = getDrawableState();

    String text_str = getText().toString();
    // 当前所在行的Y向偏移
    int currentLineOffsetY = getPaddingTop();
    currentLineOffsetY += getTextSize();

    Layout layout = getLayout();

    //循环每一行,绘制文字
    for (int i = 0; i < layout.getLineCount(); i++) {
        int lineStart = layout.getLineStart(i);
        int lineEnd = layout.getLineEnd(i);
        //获取到TextView每行中的内容
        String line_str = text_str.substring(lineStart, lineEnd);
        // 获取每行字符串的宽度(不包括字符间距)
        float desiredWidth = StaticLayout.getDesiredWidth(text_str, lineStart, lineEnd, getPaint());

        if (isLineNeedJustify(line_str)) {
            //最后一行不需要重绘
            if (i == layout.getLineCount() - 1) {
                canvas.drawText(line_str, getPaddingLeft(), currentLineOffsetY, textPaint);
            } else {
                drawJustifyTextForLine(canvas, line_str, desiredWidth, currentLineOffsetY);
            }
        } else {
            canvas.drawText(line_str, getPaddingLeft(), currentLineOffsetY, textPaint);
        }
        //更新行Y向偏移
        currentLineOffsetY += getLineHeight();
    }
}
 
Example 17
Source File: LongClickableLinkMovementMethod.java    From iBeebo with GNU General Public License v3.0 4 votes vote down vote up
private boolean action(int what, TextView widget, Spannable buffer) {
    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);

    MyURLSpan[] candidates = buffer.getSpans(first, last, MyURLSpan.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;
            }

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

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

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

        case UP:
            int best_start = -1;
            int best_end = -1;

            for (MyURLSpan candidate1 : candidates) {
                int end = buffer.getSpanEnd(candidate1);

                if (end < selEnd || selStart == selEnd) {
                    if (end > best_end) {
                        best_start = buffer.getSpanStart(candidate1);
                        best_end = end;
                    }
                }
            }

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

            break;

        case DOWN:
            best_start = Integer.MAX_VALUE;
            best_end = Integer.MAX_VALUE;

            for (MyURLSpan candidate : candidates) {
                int start = buffer.getSpanStart(candidate);

                if (start > selStart || selStart == selEnd) {
                    if (start < best_start) {
                        best_start = start;
                        best_end = buffer.getSpanEnd(candidate);
                    }
                }
            }

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

            break;
    }

    return false;
}
 
Example 18
Source File: LinkMovementMethod.java    From ForPDA with GNU General Public License v3.0 4 votes vote down vote up
private boolean action(int what, TextView widget, Spannable buffer) {
    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 (ClickableSpan candidate1 : candidates) {
                int end = buffer.getSpanEnd(candidate1);

                if (end < selEnd || selStart == selEnd) {
                    if (end > bestend) {
                        beststart = buffer.getSpanStart(candidate1);
                        bestend = end;
                    }
                }
            }

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

            break;

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

            for (ClickableSpan candidate : candidates) {
                int start = buffer.getSpanStart(candidate);

                if (start > selStart || selStart == selEnd) {
                    if (start < beststart) {
                        beststart = start;
                        bestend = buffer.getSpanEnd(candidate);
                    }
                }
            }

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

            break;
    }

    return false;
}
 
Example 19
Source File: LinkMovementMethod2.java    From EhViewer with Apache License 2.0 4 votes vote down vote up
private boolean action(int what, TextView widget, Spannable buffer) {
    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;
}
 
Example 20
Source File: LinkMovementMethod2.java    From Nimingban with Apache License 2.0 4 votes vote down vote up
private boolean action(int what, TextView widget, Spannable buffer) {
    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;
}