如何在当前光标段上设置AlignSpan Style?

时间:2014-09-02 02:25:15

标签: android android-edittext paragraph text-alignment spannablestring

我知道将样式设置为spannable,我们可以使用setSpan(Object classOfStyle,int start,int end,int flags)。 我想将alconpan设置为当前段落。当前光标位置检测到当前段落。有可能吗?我可以获得段落的起始位置和结束位置吗?

修改:

段落是一组句子。其中一段将以" Enter Character"结束。

2 个答案:

答案 0 :(得分:1)

我已经编写了一个小助手类(针对速度进行了优化),可以完全按照您的意愿进行操作。您传递一个Spannable对象,该对象将被解析以查找所有段落:

public class Layout {
    private static final Pattern LINEBREAK_PATTERN = Pattern.compile("\\r\\n|\\r|\\n");

    private int mNrOfLines = 0;
    private ArrayList<Selection> mSelection = new ArrayList<Selection>();

    public Layout(Spannable spannable) {
        String s = spannable.toString();

        // remove the trailing line feeds
        int len = s.length();
        char c = len > 0 ? s.charAt(len - 1) : '-';
        while (len > 0 && (c == '\n' || c == '\r')) {
            len--;
            c = s.charAt(len - 1);
        }

        // now find the line breaks and the according lines / paragraphs
        mNrOfLines = 1;
        Matcher m = LINEBREAK_PATTERN.matcher(s.substring(0, len));
        int groupStart = 0; 
        while (m.find()) {
            mSelection.add( new Selection(groupStart, m.end()) );
            groupStart = m.end();
            mNrOfLines++;
        }
        if (groupStart < len) {
            mSelection.add( new Selection(groupStart, len) );
        }
    }

    public List<Selection> getParagraphs() {
        return mSelection;
    }

    public int getLineForOffset(int offset) {
        int lineNr = 0;
        while(lineNr < mNrOfLines && offset >= mSelection.get(lineNr).end()) {
            lineNr++;
        }
        return Math.min(Math.max(0, lineNr), mSelection.size() - 1);
    }

    public int getLineStart(int line) {
        return mNrOfLines == 0 || line < 0 ? 0 :
               line<mNrOfLines ? mSelection.get(line).start() :
               mSelection.get(mNrOfLines-1).end()-1;
    }

    public int getLineEnd(int line) {
        return mNrOfLines == 0 || line < 0 ? 0 :
               line<mNrOfLines ? mSelection.get(line).end() :
               mSelection.get(mNrOfLines-1).end()-1;
    }
}

getLineForOffset,getLineStart和getLineEnd这三个方法可用于查找当前Selection的段落。 Selection可以是当前光标位置(基本上是带有start == end的Selection)或所选文本。以下代码将返回当前选择的所选段落:

Selection getParagraphs(EditText editor) {    
    Layout layout = new Layout( editor.getEditableText() );

    int selStart = editor.getSelectionStart();
    int selEnd = editor.getSelectionEnd();

    int firstLine = layout.getLineForOffset(selStart);
    int end = selStart == selEnd ? selEnd : selEnd - 1; 
    int lastLine = layout.getLineForOffset(end);

    return new Selection(layout.getLineStart(firstLine), layout.getLineEnd(lastLine));
}

如果是你的文字是:

  

第1行   l [ine 2
  线] 3
  第4行

选择[]之间的所有内容,getParagraphs()将返回第二行和第三行(它基本上扩展了所选文本以包括所有(甚至部分)选定的段落。

答案 1 :(得分:0)

我写一些方法来获取段落的第一个位置和段落的最后位置。 我不知道,哪一个是更好的表现。如果错误请纠正我。


    public static int getFirstPositionOfParagraph(String paragraph, int cursorPosition) {
        StringBuffer buffer = new StringBuffer(paragraph);
        List pos = new ArrayList();
        for (String breaker : LINE_BREAK){
          pos.add(buffer.lastIndexOf(breaker, cursorPosition));
        }
        int firstPosition = Collections.max(pos);
        return firstPosition 

      public static int getLastPositionOfParagraph(String paragraph, int cursorPosition) {
        StringBuffer buffer = new StringBuffer(paragraph);
        List pos = new ArrayList();
        for (String breaker : LINE_BREAK){
          int breakerPos = buffer.indexOf(breaker, cursorPosition);
          if (breakerPos > 0)
            pos.add(breakerPos);
        }
        return pos.size() > 0 ? Collections.min(pos) + 1 : paragraph.length();
      }