Android的TextView在显示文字的时候,如果有段中文有英文,有中文,有中文标点符号,你会发现,当要换行的时候遇到中文标点, 这一行就会空出很多空格出来
一、问题描述:
Android的TextView在显示文字的时候,如果有段中文有英文,有中文,有中文标点符号,你会发现,当要换行的时候遇到中文标点,
这一行就会空出很多空格出来。原因是:
1) TextView在显示中文的时候 标点符号不能显示在一行的行首和行尾,如果一个标点符号刚好在一行的行尾,该标点符号就会连同前一个字符跳到下一行显示;
2)一个英文单词不能被显示在两行中( TextView在显示英文时,标点符号是可以放在行尾的,但英文单词也不能分开 );
3)全角和半角的问题,汉字无论全角还是半角都是占2个字节,英文和符号在半角是占一个字节,全角是占两个字节。
二、解决方法
参考资料中:http://niufc.iteye.com/blog/1729792
可能由于时间问题,都没有很好解决我的问题。将textview中的字符全角化没有效果,去除特殊字符或将所有中文标号替换为英文标号。这个有点效果,但是产品经理说文案不符合标准。改源代码担心出问题,影响其他的应用。自定义TextView时,canvas.setViewport()这个方法的api被删了。然后各种百度查资料,很多都是转过来转过去。然并卵。后面找了好久才找到一个靠谱的。完美的解决了我的问题。
自定义TextView(直接把代码拷进去就能用)
package com.lhx.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* @author lhx
* @Date 9/8/15
*/
public class MyTextView extends TextView {
private int mLineY;
private int mViewWidth;
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onDraw(Canvas Canvas) {
TextPaint paint = getPaint();
paint.setColor(getCurrentTextColor());
paint.drawableState = getDrawableState();
mViewWidth = getMeasuredWidth();
String text = getText().toString();
mLineY = 0;
mLineY += getTextSize();
Layout layout = getLayout();
// layout.getLayout()在4.4.3出现NullPointerException
if (layout == null) {
return;
}
Paint.FontMetrics fm = paint.getFontMetrics();
int textHeight = (int) (Math.ceil(fm.descent - fm.ascent));
textHeight = (int) (textHeight * layout.getSpacingMultiplier() + layout
.getSpacingAdd());
//解决了最后一行文字间距过大的问题
for (int i = 0; i < layout.getLineCount(); i++) {
int lineStart = layout.getLineStart(i);
int lineEnd = layout.getLineEnd(i);
float width = StaticLayout.getDesiredWidth(text, lineStart,
lineEnd, getPaint());
String line = text.substring(lineStart, lineEnd);
if(i < layout.getLineCount() - 1) {
if (needScale(line)) {
drawScaledText(Canvas, lineStart, line, width);
} else {
Canvas.drawText(line, 0, mLineY, paint);
}
} else {
Canvas.drawText(line, 0, mLineY, paint);
}
mLineY += textHeight;
}
}
private void drawScaledText(Canvas Canvas, int lineStart, String line,
float lineWidth) {
float x = 0;
if (isFirstLineOfParagraph(lineStart, line)) {
String blanks = " ";
Canvas.drawText(blanks, x, mLineY, getPaint());
float bw = StaticLayout.getDesiredWidth(blanks, getPaint());
x += bw;
line = line.substring(3);
}
int gapCount = line.length() - 1;
int i = 0;
if (line.length() > 2 && line.charAt(0) == 12288
&& line.charAt(1) == 12288) {
String substring = line.substring(0, 2);
float cw = StaticLayout.getDesiredWidth(substring, getPaint());
Canvas.drawText(substring, x, mLineY, getPaint());
x += cw;
i += 2;
}
float d = (mViewWidth - lineWidth) / gapCount;
for (; i < line.length(); i++) {
String c = String.valueOf(line.charAt(i));
float cw = StaticLayout.getDesiredWidth(c, getPaint());
Canvas.drawText(c, x, mLineY, getPaint());
x += cw + d;
}
}
private boolean isFirstLineOfParagraph(int lineStart, String line) {
return line.length() > 3 && line.charAt(0) == ' '
&& line.charAt(1) == ' ';
}
private boolean needScale(String line) {
if (line == null || line.length() == 0) {
return false;
} else {
return line.charAt(line.length() - 1) != '\n';
}
}
}
<!--工作时间提醒-->
<LinearLayout
android:layout_width="match_parent"
android:id="@+id/ll_chat"
android:background="@color/topbar_chat"
android:layout_height="wrap_content">
<com.lhx.widget.MyTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tv_reminder"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_marginRight="8dp"
android:layout_marginLeft="8dp"
android:text = "服务商不管以任何形式要求线下交易,都存在诈骗的风险,请提高警惕。This is test!欢迎相互关注。有不对的地方望指出和包容。谢谢! "
android:textColor="@color/text_orange_1"/>
</LinearLayout>
以上就很好的解决了TextView中英文字符排版的问题,折腾了好久终于搞定。希望对您有点帮助。
Android的TextView在显示文字的时候,如果有段中文有英文,有中文,有中文标点符号,你会发现,当要换行的时候遇到中文标点, 这一行就会空出很多空格出来的更多相关文章
- 解决TextView在显示文字的时候,一行还没显示满就跳到下一行
转载请注明:转自 http://blog.csdn.NET/u011176685/article/details/48295185 一.问题描述: Android的TextView在显示文字的时候,如 ...
- Android 使用Font Awesome 显示文字图标
Android 使用Font Awesome 显示文字图标 简单几步就可以完成 简单的效果图: 1. 创建 assets 文件夹 在Android Studio 上的创建步骤为: 在 src/main ...
- 我的Android进阶之旅------> Android在TextView中显示图片方法
面试题:请说出Android SDK支持哪些方式显示富文本信息(不同颜色.大小.并包括图像的文本信息).并简要说明实现方法. 答案:Android SDK支持例如以下显示富文本信息的方式. 1.使用T ...
- 我的Android进阶之旅------> Android在TextView中显示图片方法
面试题:请说出Android SDK支持哪些方式显示富文本信息(不同颜色.大小.并包含图像的文本信息),并简要说明实现方法. 答案:Android SDK支持如下显示富文本信息的方式. 1.使用Tex ...
- Android在一个TextView里显示不同样式的字体
在同一个TextView里显示不同样式的字体 public void setSpan(Object what, int start, int end, int flags); 样式1:背景色.粗体.字 ...
- RecyclerView嵌套TextView时显示文字不全的解决方法之一
先描述一下这个小bug:简单的TextView嵌套RecyclerView作为itemView时,可能会在文本中出现布局覆盖的现象,itemView的布局其实很简单,就是一个RelativeLayou ...
- Android中TextView中的文字设置为不同颜色
questionDesTextView=(TextView)findViewById(R.id.question_des); SpannableStringBuilder builder = new ...
- android中textview单行显示,多余的省略
<TextView android:id="@+id/music_title" android:layout_width="wrap_content" a ...
- 我的Android进阶之旅------> Android为TextView组件中显示的文本添加背景色
通过上一篇文章 我的Android进阶之旅------> Android在TextView中显示图片方法 (地址:http://blog.csdn.net/ouyang_peng/article ...
随机推荐
- windows10桌面突然变灰了
不靠谱的第三方软件重装系统,装了以后系统有点问题,会隔一段时间变灰 了 windows+ctrl+c 直接就恢复色彩了
- 在java中使用FFmpeg处理视频与音频
FFmpeg是一个非常好用的视频处理工具,下面讲讲如何在java中使用该工具类. 一.首先,让我们来认识一下FFmpeg在Dos界面的常见操作 1.拷贝视频,并指定新的视频的名字以及格式 ffmpeg ...
- Codeforces 1207C Gas Pipeline (dp)
题目链接:http://codeforces.com/problemset/problem/1207/C 题目大意是给一条道路修管道,相隔一个单位的管道有两个柱子支撑,管道柱子高度可以是1可以是2,道 ...
- codeforces 962F.simple cycle(tarjan/点双连通分量)
题目连接:http://codeforces.com/contest/962/problem/F 题目大意是定义一个simple cycle为从一个节点开始绕环走一遍能经过simple cycle内任 ...
- 如何预测股票分析--自动ARIMA
在上一篇中,我们发现knn和线性回归一样,表现的不是特别好,来看看时间序列的表现 时间序列预测法其实是一种回归预测方法,属于定量预测,其基本原理是;一方面承认事物发展的延续性,运用过去时间序列的数据进 ...
- openshift3.10集群部署
简介 openshift是基于k8s的开源容器云. 要求 系统环境:CentOS 7.5 搭建一个master节点,两个node节点 注意: openshift3 依赖docker的版本为1.13.1 ...
- SpringCloud 设置多个运行实例的端口号
使用SpringCloud做集群,开发.测试阶段,经常要运行一个模块的多个实例,要修改端口号. 有3种方式. 方式一:配置文件 server.port=9001 方式二.修改引导类,控制台输入参数值 ...
- 关于Sublime如何配置C++环境的问题
前言 传说sublime是全球最好的编辑器,可是只是编辑器啊!!!如果要运行,对于我们这些蒟蒻来说,不得不去使用DEV_C++.我们总是幻想能让sublime变成一个轻量级IDE,那该多好啊!!! 那 ...
- Atcoder Beginner Contest151E(排列组合)
排列组合 #define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> using namespace std; ]; ; ]; long lo ...
- 五种网络IO模型以及多路复用IO中select/epoll对比
下面都是以网络读数据为例 [2阶段网络IO] 第一阶段:等待数据 wait for data 第二阶段:从内核复制数据到用户 copy data from kernel to user 下面是5种网络 ...