0

Я знаю, что для установки стиля в spannable мы можем использовать setSpan (Object classOfStyle, int start, int end, int flags). Я хочу установить alignspan в текущий абзац. Текущий абзац обнаружен текущей позицией курсора. Это возможно? Могу ли я получить начальную позицию и конечную позицию абзаца?Как установить стиль AlignSpan в текущем абзаце курсора?

Edit:

Абзац представляет собой группу предложений. Один из абзацев будет закончен «Введите символ».

+0

Определить пункт. –

+0

Извините, что он может? – ARM

+0

Если вы не знаете, что такое абзац, тогда ваши требования не ясны, и на ваш вопрос нет ответа. Попытайтесь выяснить, что вы хотите знать, прежде чем задавать вопрос о SO. –

ответ

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 может быть либо текущей позицией курсора (которая в основном равна 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
л [ине 2
линия] 3
линия 4

со всем между [] выбранными, getParagraphs() возвращает второй и третий (он в основном расширяет выделенный текст, чтобы включить все (даже частично) выбранные абзацы.

+0

Отлично .. Спасибо .. – ARM

+0

Спасибо .. Я хочу снова спросить, но извините, из темы темы. Я вижу ваше приложение для k-mail. Как вы можете создавать шрифты, возможно, только для стандартного форматирования полужирным, курсивом и подчеркиванием. Я вижу на Wordpress исходный код Android, но его много ошибок при формировании шрифта. – ARM

+0

Это не вопрос, на который я могу ответить. В моем богатом текстовом редакторе много работы, вышеприведенный код - это всего лишь небольшая часть для обработки форматирования абзаца. Вы можете проверить это для очень простого текстового редактора: https://github.com/commonsguy/cwac-richedit –

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(); 
     }