Why Android TextView text typesetting is uneven

Source: Internet
Author: User
Tags getcolor

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.