Android的TextView在显示文字的时候,如果有段中文有英文,有中文,有中文标点符号,你会发现,当要换行的时候遇到中文标点, 这一行就会空出很多空格出来

一、问题描述:

Android的TextView在显示文字的时候,如果有段中文有英文,有中文,有中文标点符号,你会发现,当要换行的时候遇到中文标点,

这一行就会空出很多空格出来。原因是:

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

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

3)全角和半角的问题,汉字无论全角还是半角都是占2个字节,英文和符号在半角是占一个字节,全角是占两个字节。

二、解决方法

参考资料中:http://niufc.iteye.com/blog/1729792 

可能由于时间问题,都没有很好解决我的问题。将textview中的字符全角化没有效果,去除特殊字符或将所有中文标号替换为英文标号。这个有点效果,但是产品经理说文案不符合标准。改源代码担心出问题,影响其他的应用。自定义TextView时,canvas.setViewport()这个方法的api被删了。然后各种百度查资料,很多都是转过来转过去。然并卵。后面找了好久才找到一个靠谱的。完美的解决了我的问题。


自定义TextView(直接把代码拷进去就能用)

[java]  view plain  copy
  1. package com.lhx.widget;  
  2. import android.content.Context;  
  3. import android.graphics.Canvas;  
  4. import android.graphics.Paint;  
  5. import android.text.Layout;  
  6. import android.text.StaticLayout;  
  7. import android.text.TextPaint;  
  8. import android.util.AttributeSet;  
  9. import android.widget.TextView;  
  10.   
  11. /** 
  12.  * @author lhx 
  13.  * @Date 9/8/15 
  14.  */  
  15. public class MyTextView extends TextView {  
  16.   
  17.     private int mLineY;  
  18.     private int mViewWidth;  
  19.   
  20.     public MyTextView(Context context, AttributeSet attrs) {  
  21.         super(context, attrs);  
  22.     }  
  23.   
  24.     @Override  
  25.     protected void onLayout(boolean changed, int left, int top, int right,  
  26.                             int bottom) {  
  27.         super.onLayout(changed, left, top, right, bottom);  
  28.     }  
  29.   
  30.     @Override  
  31.     protected void onDraw(Canvas Canvas) {  
  32.         TextPaint paint = getPaint();  
  33.         paint.setColor(getCurrentTextColor());  
  34.         paint.drawableState = getDrawableState();  
  35.         mViewWidth = getMeasuredWidth();  
  36.         String text = getText().toString();  
  37.         mLineY = 0;  
  38.         mLineY += getTextSize();  
  39.         Layout layout = getLayout();  
  40.   
  41.         // layout.getLayout()在4.4.3出现NullPointerException  
  42.         if (layout == null) {  
  43.             return;  
  44.         }  
  45.   
  46.         Paint.FontMetrics fm = paint.getFontMetrics();  
  47.   
  48.         int textHeight = (int) (Math.ceil(fm.descent - fm.ascent));  
  49.         textHeight = (int) (textHeight * layout.getSpacingMultiplier() + layout  
  50.                 .getSpacingAdd());  
  51.         //解决了最后一行文字间距过大的问题  
  52.         for (int i = 0; i < layout.getLineCount(); i++) {  
  53.             int lineStart = layout.getLineStart(i);  
  54.             int lineEnd = layout.getLineEnd(i);  
  55.             float width = StaticLayout.getDesiredWidth(text, lineStart,  
  56.                     lineEnd, getPaint());  
  57.             String line = text.substring(lineStart, lineEnd);  
  58.   
  59.             if(i < layout.getLineCount() - 1) {  
  60.                 if (needScale(line)) {  
  61.                     drawScaledText(Canvas, lineStart, line, width);  
  62.                 } else {  
  63.                     Canvas.drawText(line, 0, mLineY, paint);  
  64.                 }  
  65.             } else {  
  66.                 Canvas.drawText(line, 0, mLineY, paint);  
  67.             }  
  68.             mLineY += textHeight;  
  69.         }  
  70.     }  
  71.   
  72.     private void drawScaledText(Canvas Canvas, int lineStart, String line,  
  73.                                 float lineWidth) {  
  74.         float x = 0;  
  75.         if (isFirstLineOfParagraph(lineStart, line)) {  
  76.             String blanks = "  ";  
  77.             Canvas.drawText(blanks, x, mLineY, getPaint());  
  78.             float bw = StaticLayout.getDesiredWidth(blanks, getPaint());  
  79.             x += bw;  
  80.   
  81.             line = line.substring(3);  
  82.         }  
  83.   
  84.         int gapCount = line.length() - 1;  
  85.         int i = 0;  
  86.         if (line.length() > 2 && line.charAt(0) == 12288  
  87.                 && line.charAt(1) == 12288) {  
  88.             String substring = line.substring(02);  
  89.             float cw = StaticLayout.getDesiredWidth(substring, getPaint());  
  90.             Canvas.drawText(substring, x, mLineY, getPaint());  
  91.             x += cw;  
  92.             i += 2;  
  93.         }  
  94.   
  95.         float d = (mViewWidth - lineWidth) / gapCount;  
  96.         for (; i < line.length(); i++) {  
  97.             String c = String.valueOf(line.charAt(i));  
  98.             float cw = StaticLayout.getDesiredWidth(c, getPaint());  
  99.             Canvas.drawText(c, x, mLineY, getPaint());  
  100.             x += cw + d;  
  101.         }  
  102.     }  
  103.   
  104.     private boolean isFirstLineOfParagraph(int lineStart, String line) {  
  105.         return line.length() > 3 && line.charAt(0) == ' '  
  106.                 && line.charAt(1) == ' ';  
  107.     }  
  108.   
  109.     private boolean needScale(String line) {  
  110.         if (line == null || line.length() == 0) {  
  111.             return false;  
  112.         } else {  
  113.             return line.charAt(line.length() - 1) != '\n';  
  114.         }  
  115.     }  
  116.   
  117. }  

xml文件代码

[html]  view plain  copy
  1.   
  2.    <LinearLayout  
  3.            android:layout_width="match_parent"  
  4.            android:id="@+id/ll_chat"  
  5.            android:background="@color/topbar_chat"  
  6.            android:layout_height="wrap_content">  
  7.        <com.lhx.widget.MyTextView  
  8.                android:layout_width="match_parent"  
  9.                android:layout_height="wrap_content"  
  10.                android:id="@+id/tv_reminder"  
  11.                android:layout_marginTop="5dp"  
  12.                android:layout_marginBottom="5dp"  
  13.                android:layout_marginRight="8dp"  
  14.                android:layout_marginLeft="8dp"  
  15.                android:text = "服务商不管以任何形式要求线下交易,都存在诈骗的风险,请提高警惕。This is test!欢迎相互关注。有不对的地方望指出和包容。谢谢! "  
  16.                android:textColor="@color/text_orange_1"/>  
  17.    LinearLayout>  

以上就很好的解决了TextView中英文字符排版的问题,折腾了好久终于搞定。希望对您有点帮助。

你可能感兴趣的:(安卓)