To: http://www.cnblogs.com/baiyongquan/archive/2012/06/27/2566167.html
In the Android system, textview will wrap a line at the end of a line when there are numbers, letters, or punctuation marks. In fact, word will also wrap in advance, however, after all, on the PC end, the proportion of characters in space is relatively small, and the proportion of mobile phone characters is very large. Therefore, sometimes the system comes with textview to display a large proportion of blank spaces at the end of the line, which is very ugly. Therefore, in this case, it is necessary to create a control to display text.
Public class autobreaktextview extends textview {
Public static int m_itextheight; // text height
Public static int m_itextwidth; // text width
Private paint mpaint = NULL;
Private string = "";
Private float linespace = 0; // line spacing
Private int padding;
Public autobreaktextview (context, attributeset set ){
Super (context, set );
Windowmanager manager = (windowmanager) Context
. Getsystemservice (context. window_service );
Displaymetrics dm = new displaymetrics ();
Manager. getdefadisplay display (). getmetrics (DM );
System. Out. println ("width ------>" + DM. widthpixels );
System. Out. println ("density -------------->" + DM. Density );
M_itextwidth = (INT) (DM. widthpixels-2 * padding-(10*4 * DM. Density) + 1;
Float textsize = This. gettextsize ();
Padding = This. getpaddingleft ();
System. Out. println ("width ------------>" + m_itextwidth );
System. Out. println ("textsize ------------>" + textsize );
Mpaint = new paint ();
Mpaint. setantialias (true );
Mpaint. settextsize (textsize );
Mpaint. setcolor (color. Gray );
}
@ Override
Protected void ondraw (canvas ){
Super. ondraw (canvas );
Char ch;
Int W = 0;
Int istart = 0;
Int m_ifontheight;
Int m_irealline = 0;
Int x = Padding;
Int y = Padding;
Vector m_string = new vector ();
Fontmetrics fm = mpaint. getfontmetrics ();
M_ifontheight = (INT) math. Ceil (FM. Descent-FM. Top) + (INT) linespace; // calculate the font height (font height + row 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 ()));
}
}
}
}
Canvas. setviewport (m_itextwidth, m_itextheight );
For (INT I = 0, j = 1; 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 ){
Super. onmeasure (widthmeasurespec, heightmeasurespec );
Int measuredheight = measureheight (heightmeasurespec );
Int measuredwidth = measurewidth (widthmeasurespec );
System. Out. println ("measuredheight ------->" + measuredheight );
This. setmeasureddimension (measuredwidth, measuredheight );
This. setlayoutparams (New linearlayout. layoutparams (measuredwidth,
Measuredheight ));
}
Private int measureheight (INT measurespec ){
Int specmode = measurespec. getmode (measurespec );
Int specsize = measurespec. getsize (measurespec );
// Default size if no limits are specified.
Initheight ();
Int result = m_itextheight;
Log. E ("measureheight -------------->", result + "");
Return result;
}
Private void initheight (){
M_itextheight = 0;
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;
Log. E ("m_itextheight --------------------->", m_itextheight + "");
}
Private int measurewidth (INT measurespec ){
Int specmode = measurespec. getmode (measurespec );
Int specsize = measurespec. getsize (measurespec );
// Default size if no limits are 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 ){
String = text;
Initheight ();
Invalidate ();
Requestlayout ();
}
}
Custom Attributes are not used, and the code is not perfect and will be improved later.
Note that:
X and y in canvas. drawtext (string STR, int X, int y, paint) cannot be the upper left corner, but the lower left corner of a row, because the canvas draws text based on the baseline.
Baseline in baseline