Android TextView their own initiative to change the text layout of the reasons for the difference

Source: Internet
Author: User
Tags getcolor

There is no progress in the project today, the company backstage problem. Read the next just learn Android notes, found that TextView will take the initiative to change line, and typesetting text is not aligned. Check the information, summarize the reasons such as the following:

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, which avoids the typographical clutter caused by the occupying position. Half-width to full-width code such as the following, only need to invoke 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 the regular form 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, assuming a punctuation mark is just at the end of a line, and 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 can not be separated).

4, suppose two lines to its display effect: There are two ways

Method One:

Change the Android source code, the Frameworks/base/core/java/android/text under the Staticlayout.java file, such as the following:

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;

}

You can get rid of it. After removing the punctuation marks can be displayed at the beginning and end of the line, English words can also be separated in two lines display.

Method Two:

Define the view display text yourself

The internet has the talent to use their own definition of the view to solve the problem, I did the experiment and summed up a bit:

To define the view yourself:

1) Inherit the view class or its subclasses, the sample inherits the TextView class;

2) Write the constructor, get the attribute through XML (this step can define its own attribute, see the routine);

3) overrides some functions of the parent class, usually a function that begins with on, and overrides the OnDraw () and Onmeasure () functions in the sample;

=========================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 only available in the UI thread at this moment enough to draw the text out, 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 property of its own definition, placed under Project Res/values

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

=======================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 defines the view for itself, and the attribute that begins with the Cy namespace is its own definition;

=======================main.java=============================

public class Main extends Activity {

Cytextview Mcytextview;

String Text = "Android provides a static and powerful component model to build the UI portion of the user. Mainly based on the layout class: View and ViewGroup. Based on this, the Android platform offers a large number of pre-fabricated view and xxxviewgroup subclasses, i.e. layout and form widgets (widgets). The ability to build your own UI with them. ";

@Override

public void OnCreate (Bundle savedinstancestate) {

Super.oncreate (savedinstancestate);

This.setcontentview (R.layout.main);

Mcytextview = (Cytextview) Findviewbyid (R.ID.MV);

Mcytextview.settext (text);

}

}

Android TextView their own initiative to change the text layout of the reasons for the difference

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.