Как предотвратить редактирование текста после пунктуации - PullRequest
4 голосов
/ 26 мая 2011

По умолчанию Android EditText разорвет строку, если строка длиннее, чем вид, например:

Thisisalineanditisveryverylongs (end of view)
othisisanotherline

или если строка содержит знак пунктуации, например:

Thisisalineanditsnotsolong;     (several characters from the end of view)
butthisisanotherline

Как требование моей работы, текст должен разбивать строку, только если строка длиннее, чем вид, например:

Thisisalineanditsnotsolong;andt (end of view)
hisisanotherline

Должен быть способ достичь этого, я прав? До сих пор я не нашел, чтобы сделать это.

Ответы [ 3 ]

4 голосов
/ 26 мая 2011

Способ, которым TextView (и EditText) разбивает текст, - это внутренние вызовы функций для BoringLayout. Таким образом, наилучшим способом было бы перераспределить EditText и переписать эти функции. Но это не будет тривиальной задачей.

Итак, в классе TextView есть создания разных классов для стиля текста. Тот, который мы смотрим, это DynamicLayout. В этом классе мы достигаем ссылки на класс StaticLayout (в переменной с именем reflowed). В конструкторе этого класса вы найдете алгоритм переноса текста:

/*
* From the Unicode Line Breaking Algorithm:
* (at least approximately)
*  
* .,:; are class IS: breakpoints
*      except when adjacent to digits
* /    is class SY: a breakpoint
*      except when followed by a digit.
* -    is class HY: a breakpoint
*      except when followed by a digit.
*
* Ideographs are class ID: breakpoints when adjacent,
* except for NS (non-starters), which can be broken
* after but not before.
*/

if (c == ' ' || c == '\t' ||
((c == '.'  || c == ',' || c == ':' || c == ';') &&
(j - 1 < here || !Character.isDigit(chs[j - 1 - start])) &&
(j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) ||
((c == '/' || c == '-') &&
(j + 1 >= next || !Character.isDigit(chs[j + 1 - start]))) ||
(c >= FIRST_CJK && isIdeographic(c, true) &&
j + 1 < next && isIdeographic(chs[j + 1 - start], false))) {
okwidth = w;
ok = j + 1;

Вот куда идет упаковка. Так что вам нужно будет создать подкласс, позаботиться о StaticLayout, DynamicLayout, TextView и, наконец, EditText, который - я уверен - станет кошмаром :( Я даже не уверен, как пойдет весь поток. Если хотите - сначала посмотрите на TextView и проверьте вызовы getLinesCount - это будет отправной точкой.

3 голосов
/ 27 сентября 2011

Этот алгоритм разрыва строки в Android действительно отстой, он даже логически не корректен - запятая не может быть последним символом строки. он создает только ненужные разрывы строк, что приводит к очень странной разметке текста.

1 голос
/ 30 января 2013

Привет. Вот один из методов, который я сначала получил от другого парня, а потом немного изменил, он действительно работает, и вы можете попробовать.

//half ASCII transfer to full ASCII
public static String ToSBC(String input) { 
    char[] c = input.toCharArray(); 
    for (int i = 0; i< c.length; i++) { 
    if (c[i] == 32) { 
    c[i] = (char) 12288; 
    continue; 
    } 
    if (c[i]<=47 && c[i]>32 ) 
    c[i] = (char) (c[i] + 65248); 
    } 
    return new String(c); 
    }
}

вот оно. Я изменяю некоторые специальные символы с половины угла на полный угол, такие как "," ".", И эффект довольно хороший. Вы можете попробовать.

...