There is no progress in the project today, the company backstage problem. Look at the next time you learned Android notes, found that TextView will automatically wrap, and typesetting text is uneven. Check the information, the reasons are summarized as follows:
1, half-width characters and full-width character confusion caused by: this is usually the Chinese characters and numbers, the English alphabet mixed
Workaround One:
Embox the characters in the TextView. All numbers, letters, and punctuation are all converted to full-width characters, making them two bytes with Chinese characters, so you can avoid the typographical clutter caused by the occupying position. The code for half-width to full-width is as follows: just call it.
public static string Todbc (string input) {
Char[] C = Input.tochararray ();
for (int i = 0; i< c.length; i++) {
if (c[i] = = 12288) {
C[i] = (char) 32;
Continue
}if (c[i]> 65280&& c[i]< 65375)
C[i] = (char) (C[i]-65248);
}
return new String (c);
}
Workaround Two:
Remove special characters or replace all Chinese labels with English numerals. Use regular expressions to filter all special characters, or use ReplaceAll () to replace Chinese labels with English numerals. After the conversion, you can solve the problem of typesetting confusion.
Replace, filter special characters
public static string Stringfilter (String str) throws patternsyntaxexception{
Str=str.replaceall ("" "," ["). ReplaceAll (" "", "]"). ReplaceAll ("!", "!"); /Replace Chinese marking
String regex= "[" "]"; Clear out special characters
Pattern p = pattern.compile (regEx);
Matcher m = p.matcher (str);
Return M.replaceall (""). Trim ();
}
2. TextView when displaying Chinese punctuation marks cannot be displayed at the beginning and end of a line, and if a punctuation mark is just at the end of a line, the punctuation mark jumps to the next line along with the previous character.
Workaround: Add a space after the punctuation.
3, an English word can not be displayed in two lines (TextView in English, punctuation can be placed at the end of the line, but the English words cannot be separated).
4. If you want two lines to display the effect: there are two ways
Method One:
Modify the Android source code; Frameworks/base/core/java/android/text The following code in the Staticlayout.java file:
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;
if (Fittop < oktop)
Oktop = Fittop;
if (Fitascent < okascent)
Okascent = fitascent;
if (Fitdescent > Okdescent)
Okdescent = fitdescent;
if (Fitbottom > Okbottom)
Okbottom = Fitbottom;
}
get rid of it. After removing the punctuation marks can be displayed at the beginning and end of the line, the English words can also be separated in two lines display.
Method Two:
Customizing view display text
The internet has the talent to use a custom view to solve this problem, I did the experiment and summed up a bit:
To customize the view:
1) Inherit the view class or its subclasses, the example inherits the TextView class;
2) Write the constructor, get the attributes through XML (this step can be custom attributes, see routines);
3) overrides some functions of the parent class, usually the function that begins with on, and overrides the OnDraw () and Onmeasure () functions in the example;
=========================cytextview.java=============================
public class Cytextview extends TextView {
public static int m_itextheight; Height of text
public static int m_itextwidth;//width of text
Private Paint mpaint = null;
Private String string= "";
private float linespace = 0;//line Spacing
Public Cytextview (context context, AttributeSet set)
{
Super (Context,set);
TypedArray TypedArray = context.obtainstyledattributes (set, R.styleable.cytextview);
int width = Typedarray.getint (r.styleable. CY Textview_textwidth, 320);
float textsize = typedarray.getdimension (r.styleable. CY Textview_textsize, 24);
int textcolor = Typedarray.getcolor (r.styleable. CY Textview_textcolor,-1442840576);
float linespace = typedarray.getdimension (r.styleable. CY Textview_linespacingextra, 15);
int typeface = Typedarray.getcolor (r.styleable. CY textview_typeface, 0);
Typedarray.recycle ();
Sets the width and line spacing of the CY TextView www.linuxidc.com
M_itextwidth=width;
Linespace=linespace;
Building a Paint object
Mpaint = new Paint ();
Mpaint.setantialias (TRUE);
Mpaint.setcolor (TextColor);
Mpaint.settextsize (TEXTSIZE);
Switch (typeface) {
Case 0:
Mpaint.settypeface (Typeface.default);
Break
Case 1:
Mpaint.settypeface (Typeface.sans_serif);
Break
Case 2:
Mpaint.settypeface (Typeface.serif);
Break
Case 3:
Mpaint.settypeface (Typeface.monospace);
Break
Default
Mpaint.settypeface (Typeface.default);
Break
}
}
@Override
protected void OnDraw (canvas canvas)
{
Super.ondraw (canvas);
Char ch;
int w = 0;
int istart = 0;
int m_ifontheight;
int m_irealline=0;
int x=2;
int y=30;
Vector m_string=new vector ();
FontMetrics fm = Mpaint.getfontmetrics ();
M_ifontheight = (int) Math.ceil (fm.descent-fm.top) + (int) linespace;//calculate font height (font height + line spacing)
for (int i = 0; i < string.length (); i++)
{
ch = string.charat (i);
Float[] widths = new float[1];
String srt = string.valueof (CH);
Mpaint.gettextwidths (srt, widths);
if (ch = = '/n ') {
m_irealline++;
M_string.addelement (string.substring (Istart, i));
Istart = i + 1;
w = 0;
}else{
W + = (int) (Math.ceil (widths[0]));
if (W > M_itextwidth) {
m_irealline++;
M_string.addelement (string.substring (Istart, i));
Istart = i;
i--;
w = 0;
}else{
if (i = = (String.Length ()-1)) {
m_irealline++;
M_string.addelement (String.substring (Istart, String.Length ()));
}
}
}
}
m_itextheight=m_irealline*m_ifontheight+2;
Canvas.setviewport (M_itextwidth, m_itextwidth);
for (int i = 0, j = 0; i < M_irealline; i++, J + +)
{
Canvas.drawtext (String) (M_string.elementat (i)), X, Y+m_ifontheight * j, Mpaint);
}
}
protected void onmeasure (int widthmeasurespec, int heightmeasurespec)
{
int measuredheight = Measureheight (Heightmeasurespec);
int measuredwidth = Measurewidth (Widthmeasurespec);
This.setmeasureddimension (Measuredwidth, measuredheight);
This.setlayoutparams (New Linearlayout.layoutparams (measuredwidth,measuredheight));
Super.onmeasure (Widthmeasurespec, Heightmeasurespec);
}
private int measureheight (int measurespec)
{
int specmode = Measurespec.getmode (Measurespec);
int specsize = measurespec.getsize (Measurespec);
The Default size if no limits is specified.
Initheight ();
int result = M_itextheight;
if (Specmode = = Measurespec.at_most) {
Calculate the ideal size of your
Control within this maximum size.
If your control fills the available
Space return the outer bound.
result = Specsize;
}else if (Specmode = = measurespec.exactly) {
If your control can fit within these bounds return that value.
result = Specsize;
}
return result;
}
private void Initheight ()
{
Set the initial height of CY textview to 0
m_itextheight=0;
Approximate calculation of the required height of CY TextView
FontMetrics fm = Mpaint.getfontmetrics ();
int m_ifontheight = (int) Math.ceil (fm.descent-fm.top) + (int) linespace;
int line=0;
int istart=0;
int w=0;
for (int i = 0; i < string.length (); i++)
{
char ch = string.charat (i);
Float[] widths = new float[1];
String srt = string.valueof (CH);
Mpaint.gettextwidths (srt, widths);
if (ch = = '/n ') {
line++;
Istart = i + 1;
w = 0;
}else{
W + = (int) (Math.ceil (widths[0]));
if (W > M_itextwidth) {
line++;
Istart = i;
i--;
w = 0;
}else{
if (i = = (String.Length ()-1)) {
line++;
}
}
}
}
m_itextheight= (line) *m_ifontheight+2;
}
private int measurewidth (int measurespec)
{
int specmode = Measurespec.getmode (Measurespec);
int specsize = measurespec.getsize (Measurespec);
The Default size if no limits is specified.
int result = 500;
if (Specmode = = Measurespec.at_most) {
Calculate the ideal size of your control
Within this maximum size.
If your control fills the available space
Return the outer bound.
result = Specsize;
}else if (Specmode = = measurespec.exactly) {
If your control can fit within these bounds return that value.
result = Specsize;
}
return result;
}
public void SetText (String text) (Note: This function is currently only called in the UI thread to draw the text, in other threads
Cannot draw the text, looked for a long time cannot find the reason, asks the expert to answer)
{
string = text;
Requestlayout ();
Invalidate ();
}
}
=======================attrs.xml===============================
The file is a custom attribute, placed under the res/values of the project
=======================main.xml==========================
<scrollview< p= "" >
Xmlns:android= "Http://schemas.android.com/apk/res/android"
Android:layout_width= "320px"
android:layout_height= "320px"
Android:background= "#ffffffff"
>
<linearlayout< p= "" >
Xmlns:android= "Http://schemas.android.com/apk/res/android"
android:orientation= "Vertical"
Android:layout_width= "Fill_parent"
android:layout_height= "Fill_parent" >
<com.cy.cytextview.cytextview< p= "" >
Xmlns:cy= "Http://schemas.Android.com/apk/res/com.cy.CYTextView"
Android:id= "@+id/mv"
android:layout_height= "Wrap_content"
Android:layout_width= "Wrap_content"
Cy:textwidth= "320"
Cy:textsize= "24SP"
Cy:textcolor= "#aa000000"
Cy:linespacingextra= "15SP"
cy:typeface= "Serif" >
The blue code is the custom view, where the attribute starting with the Cy namespace is a custom attribute;
=======================main.java=============================
public class Main extends Activity {
Cytextview Mcytextview;
String Text = "Android provides a sophisticated and powerful component model to build the UI portion of the user. Mainly based on the layout class: View and ViewGroup. On this basis, the Android platform offers a large number of pre-fabricated view and xxxviewgroup subclasses, i.e. layout and widgets (widgets). You can use them to build your own UI. ";
@Override
public void OnCreate (Bundle savedinstancestate) {
Super.oncreate (savedinstancestate);
This.setcontentview (R.layout.main);
Mcytextview = (Cytextview) Findviewbyid (R.ID.MV);
Mcytextview.settext (text);
}
}
Why Android TextView text typesetting is uneven