半角字符与全角字符混乱所致:这种情况一般就是汉字与数字、英文字母混用

解决方法一:

将textview中的字符全角化。即将所有的数字、字母及标点全部转为全角字符,使它们与汉字同占两个字节,这样就可以避免由于占位导致的排版混乱问题了。



android xml textview 换行符 安卓textview自动换行_Math



1. public static
2. char[] c = input.toCharArray();  
3. for (int i = 0; i< c.length; i++) {  
4. if (c[i] == 12288) {  
5. char) 32;  
6. continue;  
7. if (c[i]> 65280&& c[i]< 65375)  
8. char) (c[i] - 65248);  
9.        }  
10. return new
11. }



 

解决方法二:

去除特殊字符或将所有中文标号替换为英文标号。利用正则表达式将所有特殊字符过滤,或利用replaceAll()将中文标号替换为英文标号。则转化之后,则可解决排版混乱问题。

 



android xml textview 换行符 安卓textview自动换行_Math



1. // 替换、过滤特殊字符
2. public static String StringFilter(String str) throws
3. "【","[").replaceAll("】","]").replaceAll("!","!");//替换中文标号
4. "[『』]"; // 清除掉特殊字符
5.     Pattern p = Pattern.compile(regEx);  
6.     Matcher m = p.matcher(str);  
7. return m.replaceAll("").trim();  
8. }



2、TextView在显示中文的时候标点符号不能显示在一行的行首和行尾,如果一个标点符号刚好在一行的行尾,该标点符号就会连同前一个字符跳到下一行显示。

解决方法:在标点符号后加一个空格。

3、一个英文单词不能被显示在两行中( TextView在显示英文时,标点符号是可以放在行尾的,但英文单词也不能分开 )。

4、如果要两行对其的显示效果:有两种方法

方法一:

修改Android源代码;将frameworks/base/core/java/android/text下的StaticLayout.java文件中的如下代码:



android xml textview 换行符 安卓textview自动换行_Math



1. if (c == ' ' || c == '/t'
2. '.'  || c == ',' || c == ':' || c == ';') &&  
3. 1 < here || !Character.isDigit(chs[j - 1
4. 1 >= next || !Character.isDigit(chs[j + 1
5. '/' || c == '-') &&  
6. 1 >= next || !Character.isDigit(chs[j + 1
7. true) &&  
8. 1 < next && isIdeographic(chs[j + 1 - start], false))) {  
9.                           okwidth = w;  
10. 1;  
11.   
12. if
13.                               oktop = fittop;  
14. if
15.                               okascent = fitascent;  
16. if
17.                               okdescent = fitdescent;  
18. if
19.                               okbottom = fitbottom;  
20.                       }



去掉就可以了。去掉后标点符号可以显示在行首和行尾,英文单词也可以被分开在两行中显示。

方法二:

自定义View显示文本

网上就有达人采用自定义View来解决这个问题,我做了实验并总结了一下:

自定义View的步骤: 

1)继承View类或其子类,例子继承了TextView类;

2)写构造函数,通过XML获取属性(这一步中可以自定义属性,见例程);

3)重写父类的某些函数,一般都是以on开头的函数,例子中重写了onDraw()和onMeasure()函数;

=========================CYTextView.java=============================



android xml textview 换行符 安卓textview自动换行_Math



1. public class CYTextView extends
2. public  static  int m_iTextHeight; //文本的高度
3. public  static  int m_iTextWidth;//文本的宽度
4.      
5. private Paint mPaint = null;  
6. private String string="";  
7. private float LineSpace = 0;//行间距
8.          
9. public
10.     {        
11. super(context,set);   
12.   
13.         TypedArray typedArray = context.obtainStyledAttributes(set, R.styleable.CYTextView);  
14.   
15. int width = typedArray.getInt(R.styleable. CY TextView_textwidth, 320);  
16. float textsize = typedArray.getDimension(R.styleable. CY TextView_textSize, 24);  
17. int textcolor = typedArray.getColor(R.styleable. CY TextView_textColor, -1442840576);  
18. float linespace = typedArray.getDimension(R.styleable. CY TextView_lineSpacingExtra, 15);  
19. int typeface = typedArray.getColor(R.styleable. CY TextView_typeface, 0);  
20.          
21.         typedArray.recycle();  
22.          
23. //设置 CY TextView的宽度和行间距www.linuxidc.com
24.         m_iTextWidth=width;  
25.         LineSpace=linespace;  
26.          
27. // 构建paint对象     
28. new
29. true);  
30.         mPaint.setColor(textcolor);  
31.         mPaint.setTextSize(textsize);  
32. switch(typeface){  
33. case 0:  
34.             mPaint.setTypeface(Typeface.DEFAULT);  
35. break;  
36. case 1:  
37.             mPaint.setTypeface(Typeface.SANS_SERIF);  
38. break;  
39. case 2:  
40.             mPaint.setTypeface(Typeface.SERIF);  
41. break;  
42. case 3:  
43.             mPaint.setTypeface(Typeface.MONOSPACE);  
44. break;  
45. default:  
46.             mPaint.setTypeface(Typeface.DEFAULT);     
47. break;  
48.         }  
49.          
50.     }  
51.    
52. @Override
53. protected void
54.     {   
55. super.onDraw(canvas);        
56.          
57. char
58. int w = 0;  
59. int istart = 0;  
60. int
61. int m_iRealLine=0;  
62. int x=2;  
63. int y=30;  
64.          
65. new
66.          
67.         FontMetrics fm = mPaint.getFontMetrics();         
68. int) Math.ceil(fm.descent - fm.top) + (int)LineSpace;//计算字体高度(字体高度+行间距)
69.   
70. for (int i = 0; i < string.length(); i++)  
71.         {  
72.             ch = string.charAt(i);  
73. float[] widths = new float[1];  
74.             String srt = String.valueOf(ch);  
75.             mPaint.getTextWidths(srt, widths);  
76.   
77. if (ch == '/n'){  
78.                 m_iRealLine++;  
79.                 m_String.addElement(string.substring(istart, i));  
80. 1;  
81. 0;  
82. else{  
83. int) (Math.ceil(widths[0]));  
84. if
85.                     m_iRealLine++;  
86.                     m_String.addElement(string.substring(istart, i));  
87.                     istart = i;  
88.                     i--;  
89. 0;  
90. else{  
91. if (i == (string.length() - 1)){  
92.                         m_iRealLine++;  
93.                         m_String.addElement(string.substring(istart, string.length()));  
94.                     }  
95.                 }  
96.             }  
97.         }  
98. 2;  
99.         canvas.setViewport(m_iTextWidth, m_iTextWidth);  
100. for (int i = 0, j = 0; i < m_iRealLine; i++, j++)  
101.         {  
102.             canvas.drawText((String)(m_String.elementAt(i)), x,  y+m_iFontHeight * j, mPaint);  
103.         }  
104.     }   
105.     
106.      
107. protected void onMeasure(int widthMeasureSpec, int
108.     {           
109. int
110. int
111. this.setMeasuredDimension(measuredWidth, measuredHeight);  
112. this.setLayoutParams(new
113. super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
114.     }   
115.                   
116. private int measureHeight(int
117.     {   
118. int
119. int
120. // Default size if no limits are specified. 
121.         initHeight();  
122. int
123. if
124. // Calculate the ideal size of your         
125. // control within this maximum size.         
126. // If your control fills the available          
127. // space return the outer bound.         
128.             result = specSize;            
129. else if
130. // If your control can fit within these bounds return that value.           
131.             result = specSize;            
132.         }            
133. return
134.     }   
135.      
136. private void
137.     {  
138. //设置 CY TextView的初始高度为0
139. 0;  
140.          
141. //大概计算 CY TextView所需高度
142.         FontMetrics fm = mPaint.getFontMetrics();         
143. int m_iFontHeight = (int) Math.ceil(fm.descent - fm.top) + (int)LineSpace;  
144. int line=0;  
145. int istart=0;  
146.          
147. int w=0;  
148. for (int i = 0; i < string.length(); i++)  
149.         {  
150. char
151. float[] widths = new float[1];  
152.             String srt = String.valueOf(ch);  
153.             mPaint.getTextWidths(srt, widths);  
154.   
155. if (ch == '/n'){  
156.                 line++;  
157. 1;  
158. 0;  
159. else{  
160. int) (Math.ceil(widths[0]));  
161. if
162.                     line++;  
163.                     istart = i;  
164.                     i--;  
165. 0;  
166. else{  
167. if (i == (string.length() - 1)){  
168.                         line++;  
169.                     }  
170.                 }  
171.             }  
172.         }  
173. 2;  
174.     }  
175.                   
176. private int measureWidth(int
177.     {   
178. int
179. int
180.            
181. // Default size if no limits are specified.         
182. int result = 500;           
183. if
184. // Calculate the ideal size of your control          
185. // within this maximum size.        
186. // If your control fills the available space        
187. // return the outer bound.        
188.             result = specSize;           
189. else if
190. // If your control can fit within these bounds return that value.          
191.             result = specSize;             
192.         }            
193. return
194.     }  
195. public void SetText(String text)(//注:此函数目前只有在UI线程中调用才可以把文本画出来,在其它线程中<p>                                                        //无法画文本,找了好久找不到原因,求高手解答)
196.     {  
197.         string = text;  
198. // requestLayout();
199. // invalidate();
200.     }    
201. }</p>



=======================attrs.xml===============================

该文件是自定义的属性,放在工程的res/values下



android xml textview 换行符 安卓textview自动换行_Math



1. <resources>  
2. "textwidth" format="integer"/>  
3. "typeface">  
4. enum name="normal" value="0"/>  
5. enum name="sans" value="1"/>  
6. enum name="serif" value="2"/>  
7. enum name="monospace" value="3"/>  
8.     </attr>  
9.   
10. "CYTextView">     
11. "textwidth"
12. "textSize" format="dimension"/>  
13. "textColor" format="reference|color"/>  
14. "lineSpacingExtra" format="dimension"/>  
15. "typeface"
16.         </declare-styleable>  
17. </resources>



=======================main.xml==========================



android xml textview 换行符 安卓textview自动换行_Math



1. <?xml version="1.0" encoding="utf-8"?>  
2. <ScrollView  
3. "http://schemas.android.com/apk/res/android"
4. "320px"
5. "320px"
6. "#ffffffff"
7.         >  
8.   <LinearLayout  
9. "http://schemas.android.com/apk/res/android"
10. "vertical"
11. "fill_parent"
12. "fill_parent">  
13.     <com.cy.CYTextView.CYTextView  
14. "http://schemas.Android.com/apk/res/ com.cy.CYTextView "
15. "@+id/mv"
16. "wrap_content"
17. "wrap_content"
18. "320"
19. "24sp"
20. "#aa000000"
21. "15sp"
22. "serif">  
23.     </com. cy .CYTextView.CYTextView>     
24.   </LinearLayout>  
25. </ScrollView>



 

蓝色代码即为自定义View,其中以cy命名空间开头的属性是自定义属性;

=======================Main.java=============================



android xml textview 换行符 安卓textview自动换行_Math



1. public class Main extends
2.     CYTextView mCYTextView;  
3. "Android提供了精巧和有力的组件化模型构建用户的UI部分。主要是基于布局类:View和        ViewGroup。在此基础上,android平台提供了大量的预制的View和xxxViewGroup子类,即布局(layout)和窗口小部件(widget)。可以用它们构建自己的UI。";  
4.      
5.      
6. @Override
7. public void
8. super.onCreate(savedInstanceState);  
9. this.setContentView(R.layout.main);  
10.          
11.         mCYTextView = (CYTextView)findViewById(R.id.mv);  
12.         mCYTextView.SetText(text);  
13.     }  
14.   
15. }



 


半角字符与全角字符混乱所致:这种情况一般就是汉字与数字、英文字母混用

解决方法一:

将textview中的字符全角化。即将所有的数字、字母及标点全部转为全角字符,使它们与汉字同占两个字节,这样就可以避免由于占位导致的排版混乱问题了。



android xml textview 换行符 安卓textview自动换行_Math



1. public static
2. char[] c = input.toCharArray();  
3. for (int i = 0; i< c.length; i++) {  
4. if (c[i] == 12288) {  
5. char) 32;  
6. continue;  
7. if (c[i]> 65280&& c[i]< 65375)  
8. char) (c[i] - 65248);  
9.        }  
10. return new
11. }



 

解决方法二:

去除特殊字符或将所有中文标号替换为英文标号。利用正则表达式将所有特殊字符过滤,或利用replaceAll()将中文标号替换为英文标号。则转化之后,则可解决排版混乱问题。

 



android xml textview 换行符 安卓textview自动换行_Math



1. // 替换、过滤特殊字符
2. public static String StringFilter(String str) throws
3. "【","[").replaceAll("】","]").replaceAll("!","!");//替换中文标号
4. "[『』]"; // 清除掉特殊字符
5.     Pattern p = Pattern.compile(regEx);  
6.     Matcher m = p.matcher(str);  
7. return m.replaceAll("").trim();  
8. }
  1.  



2、TextView在显示中文的时候标点符号不能显示在一行的行首和行尾,如果一个标点符号刚好在一行的行尾,该标点符号就会连同前一个字符跳到下一行显示。

解决方法:在标点符号后加一个空格。

3、一个英文单词不能被显示在两行中( TextView在显示英文时,标点符号是可以放在行尾的,但英文单词也不能分开 )。

4、如果要两行对其的显示效果:有两种方法

方法一:

修改Android源代码;将frameworks/base/core/java/android/text下的StaticLayout.java文件中的如下代码:



android xml textview 换行符 安卓textview自动换行_Math



1. if (c == ' ' || c == '/t'
2. '.'  || c == ',' || c == ':' || c == ';') &&  
3. 1 < here || !Character.isDigit(chs[j - 1
4. 1 >= next || !Character.isDigit(chs[j + 1
5. '/' || c == '-') &&  
6. 1 >= next || !Character.isDigit(chs[j + 1
7. true) &&  
8. 1 < next && isIdeographic(chs[j + 1 - start], false))) {  
9.                           okwidth = w;  
10. 1;  
11.   
12. if
13.                               oktop = fittop;  
14. if
15.                               okascent = fitascent;  
16. if
17.                               okdescent = fitdescent;  
18. if
19.                               okbottom = fitbottom;  
20.                       }



去掉就可以了。去掉后标点符号可以显示在行首和行尾,英文单词也可以被分开在两行中显示。

方法二:

自定义View显示文本

网上就有达人采用自定义View来解决这个问题,我做了实验并总结了一下:

自定义View的步骤: 

1)继承View类或其子类,例子继承了TextView类;

2)写构造函数,通过XML获取属性(这一步中可以自定义属性,见例程);

3)重写父类的某些函数,一般都是以on开头的函数,例子中重写了onDraw()和onMeasure()函数;

=========================CYTextView.java=============================



android xml textview 换行符 安卓textview自动换行_Math



    1. public class CYTextView extends
    2. public  static  int m_iTextHeight; //文本的高度
    3. public  static  int m_iTextWidth;//文本的宽度
    4.      
    5. private Paint mPaint = null;  
    6. private String string="";  
    7. private float LineSpace = 0;//行间距
    8.          
    9. public
    10.     {        
    11. super(context,set);   
    12.   
    13.         TypedArray typedArray = context.obtainStyledAttributes(set, R.styleable.CYTextView);  
    14.   
    15. int width = typedArray.getInt(R.styleable. CY TextView_textwidth, 320);  
    16. float textsize = typedArray.getDimension(R.styleable. CY TextView_textSize, 24);  
    17. int textcolor = typedArray.getColor(R.styleable. CY TextView_textColor, -1442840576);  
    18. float linespace = typedArray.getDimension(R.styleable. CY TextView_lineSpacingExtra, 15);  
    19. int typeface = typedArray.getColor(R.styleable. CY TextView_typeface, 0);  
    20.          
    21.         typedArray.recycle();  
    22.          
    23. //设置 CY TextView的宽度和行间距www.linuxidc.com
    24.         m_iTextWidth=width;  
    25.         LineSpace=linespace;  
    26.          
    27. // 构建paint对象     
    28. new
    29. true);  
    30.         mPaint.setColor(textcolor);  
    31.         mPaint.setTextSize(textsize);  
    32. switch(typeface){  
    33. case 0:  
    34.             mPaint.setTypeface(Typeface.DEFAULT);  
    35. break;  
    36. case 1:  
    37.             mPaint.setTypeface(Typeface.SANS_SERIF);  
    38. break;  
    39. case 2:  
    40.             mPaint.setTypeface(Typeface.SERIF);  
    41. break;  
    42. case 3:  
    43.             mPaint.setTypeface(Typeface.MONOSPACE);  
    44. break;  
    45. default:  
    46.             mPaint.setTypeface(Typeface.DEFAULT);     
    47. break;  
    48.         }  
    49.          
    50.     }  
    51.    
    52. @Override
    53. protected void
    54.     {   
    55. super.onDraw(canvas);        
    56.          
    57. char
    58. int w = 0;  
    59. int istart = 0;  
    60. int
    61. int m_iRealLine=0;  
    62. int x=2;  
    63. int y=30;  
    64.          
    65. new
    66.          
    67.         FontMetrics fm = mPaint.getFontMetrics();         
    68. int) Math.ceil(fm.descent - fm.top) + (int)LineSpace;//计算字体高度(字体高度+行间距)
    69.   
    70. for (int i = 0; i < string.length(); i++)  
    71.         {  
    72.             ch = string.charAt(i);  
    73. float[] widths = new float[1];  
    74.             String srt = String.valueOf(ch);  
    75.             mPaint.getTextWidths(srt, widths);  
    76.   
    77. if (ch == '/n'){  
    78.                 m_iRealLine++;  
    79.                 m_String.addElement(string.substring(istart, i));  
    80. 1;  
    81. 0;  
    82. else{  
    83. int) (Math.ceil(widths[0]));  
    84. if
    85.                     m_iRealLine++;  
    86.                     m_String.addElement(string.substring(istart, i));  
    87.                     istart = i;  
    88.                     i--;  
    89. 0;  
    90. else{  
    91. if (i == (string.length() - 1)){  
    92.                         m_iRealLine++;  
    93.                         m_String.addElement(string.substring(istart, string.length()));  
    94.                     }  
    95.                 }  
    96.             }  
    97.         }  
    98. 2;  
    99.         canvas.setViewport(m_iTextWidth, m_iTextWidth);  
    100. for (int i = 0, j = 0; i < m_iRealLine; i++, j++)  
    101.         {  
    102.             canvas.drawText((String)(m_String.elementAt(i)), x,  y+m_iFontHeight * j, mPaint);  
    103.         }  
    104.     }   
    105.     
    106.      
    107. protected void onMeasure(int widthMeasureSpec, int
    108.     {           
    109. int
    110. int
    111. this.setMeasuredDimension(measuredWidth, measuredHeight);  
    112. this.setLayoutParams(new
    113. super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
    114.     }   
    115.                   
    116. private int measureHeight(int
    117.     {   
    118. int
    119. int
    120. // Default size if no limits are specified. 
    121.         initHeight();  
    122. int
    123. if
    124. // Calculate the ideal size of your         
    125. // control within this maximum size.         
    126. // If your control fills the available          
    127. // space return the outer bound.         
    128.             result = specSize;            
    129. else if
    130. // If your control can fit within these bounds return that value.           
    131.             result = specSize;            
    132.         }            
    133. return
    134.     }   
    135.      
    136. private void
    137.     {  
    138. //设置 CY TextView的初始高度为0
    139. 0;  
    140.          
    141. //大概计算 CY TextView所需高度
    142.         FontMetrics fm = mPaint.getFontMetrics();         
    143. int m_iFontHeight = (int) Math.ceil(fm.descent - fm.top) + (int)LineSpace;  
    144. int line=0;  
    145. int istart=0;  
    146.          
    147. int w=0;  
    148. for (int i = 0; i < string.length(); i++)  
    149.         {  
    150. char
    151. float[] widths = new float[1];  
    152.             String srt = String.valueOf(ch);  
    153.             mPaint.getTextWidths(srt, widths);  
    154.   
    155. if (ch == '/n'){  
    156.                 line++;  
    157. 1;  
    158. 0;  
    159. else{  
    160. int) (Math.ceil(widths[0]));  
    161. if
    162.                     line++;  
    163.                     istart = i;  
    164.                     i--;  
    165. 0;  
    166. else{  
    167. if (i == (string.length() - 1)){  
    168.                         line++;  
    169.                     }  
    170.                 }  
    171.             }  
    172.         }  
    173. 2;  
    174.     }  
    175.                   
    176. private int measureWidth(int
    177.     {   
    178. int
    179. int
    180.            
    181. // Default size if no limits are specified.         
    182. int result = 500;           
    183. if
    184. // Calculate the ideal size of your control          
    185. // within this maximum size.        
    186. // If your control fills the available space        
    187. // return the outer bound.        
    188.             result = specSize;           
    189. else if
    190. // If your control can fit within these bounds return that value.          
    191.             result = specSize;             
    192.         }            
    193. return
    194.     }  
    195. public void SetText(String text)(//注:此函数目前只有在UI线程中调用才可以把文本画出来,在其它线程中<p>                                                        //无法画文本,找了好久找不到原因,求高手解答)
    196.     {  
    197.         string = text;  
    198. // requestLayout();
    199. // invalidate();
    200.     }    
    201. }</p>



    =======================attrs.xml===============================

    该文件是自定义的属性,放在工程的res/values下



    android xml textview 换行符 安卓textview自动换行_Math



    1. <resources>  
    2. "textwidth" format="integer"/>  
    3. "typeface">  
    4. enum name="normal" value="0"/>  
    5. enum name="sans" value="1"/>  
    6. enum name="serif" value="2"/>  
    7. enum name="monospace" value="3"/>  
    8.     </attr>  
    9.   
    10. "CYTextView">     
    11. "textwidth"
    12. "textSize" format="dimension"/>  
    13. "textColor" format="reference|color"/>  
    14. "lineSpacingExtra" format="dimension"/>  
    15. "typeface"
    16.         </declare-styleable>  
    17. </resources>



    =======================main.xml==========================



    android xml textview 换行符 安卓textview自动换行_Math



    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <ScrollView  
    3. "http://schemas.android.com/apk/res/android"
    4. "320px"
    5. "320px"
    6. "#ffffffff"
    7.         >  
    8.   <LinearLayout  
    9. "http://schemas.android.com/apk/res/android"
    10. "vertical"
    11. "fill_parent"
    12. "fill_parent">  
    13.     <com.cy.CYTextView.CYTextView  
    14. "http://schemas.Android.com/apk/res/ com.cy.CYTextView "
    15. "@+id/mv"
    16. "wrap_content"
    17. "wrap_content"
    18. "320"
    19. "24sp"
    20. "#aa000000"
    21. "15sp"
    22. "serif">  
    23.     </com. cy .CYTextView.CYTextView>     
    24.   </LinearLayout>  
    25. </ScrollView>



     

    蓝色代码即为自定义View,其中以cy命名空间开头的属性是自定义属性;

    =======================Main.java=============================



    android xml textview 换行符 安卓textview自动换行_Math



    1. public class Main extends
    2.     CYTextView mCYTextView;  
    3. "Android提供了精巧和有力的组件化模型构建用户的UI部分。主要是基于布局类:View和        ViewGroup。在此基础上,android平台提供了大量的预制的View和xxxViewGroup子类,即布局(layout)和窗口小部件(widget)。可以用它们构建自己的UI。";  
    4.      
    5.      
    6. @Override
    7. public void
    8. super.onCreate(savedInstanceState);  
    9. this.setContentView(R.layout.main);  
    10.          
    11.         mCYTextView = (CYTextView)findViewById(R.id.mv);  
    12.         mCYTextView.SetText(text);  
    13.     }  
    14.   
    15. }