Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
385 views
in Technique[技术] by (71.8m points)

android - How to prevent EditText from breaking a line after punctuation

As default, an Android EditText will break a line if the line is longer than the view, like this:

Thisisalineanditisveryverylongs (end of view)
othisisanotherline

or if the line contains a punctuation character, like this:

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

As a requirement of my work, the text has to break a line only if the line is longer than the view, like this:

Thisisalineanditsnotsolong;andt (end of view)
hisisanotherline

There must be a way to achieve this, am I right? So far I haven't found anyway to do this.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The way TextView (and EditText) breaks the text is through private function calls to BoringLayout internally. So, the best way would be to sublcass EditText and rewrite these functions. But it will not be a trivial task.

So, in the TextView class there are creations of different classes for text style. The one we look is DynamicLayout. In this class we reach to a reference of the class StaticLayout (in a variable called reflowed). In the constructor of this class you will find the text wrap algorithm:

/*
* 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 == '' ||
((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;

Here's where all the wrapping goes. So you will need to subclass take care for StaticLayout, DynamicLayout, TextView and finally EditText which - I am sure - will be a nightmare :( I am not even sure how all the flow goes. If you want - take a look at TextView first and check for getLinesCount calls - this will be the starting point.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...