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中英文字符排版的問題,折騰了好久終于搞定。希望對您有點幫助。

?

?

轉載于:https://www.cnblogs.com/lenkevin/p/8940237.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/451908.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/451908.shtml
英文地址,請注明出處:http://en.pswp.cn/news/451908.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

什么是IDE

集成開發環境&#xff08;IDE&#xff0c;Integrated Development Environment &#xff09;是用于提供程序開發環境的應用程序&#xff0c;一般包括代碼編輯器、編譯器、調試器和圖形用戶界面等工具。集成了代碼編寫功能、分析功能、編譯功能、調試功能等一體化的開發軟件服務…

vue 學習

http://jspang.com/ vue 學習 vue 學習 轉載于:https://www.cnblogs.com/qianjin888/p/9342031.html

策略模式-Strategy Pattern

解決問題 將算法按照策略或場景封裝起來&#xff0c;以方便按照不同的場景執行不同的策略。它很好的解決了通過if...else 來決策行為而帶來的代碼和邏輯復雜性。 應用場景 一個經常被拿來舉例的場景是收銀員收銀場景&#xff1a;它需要根據不同的場景&#xff08;是否為會員、有…

ssm框架下 tiles框架 的使用

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 tiles框架的工作 在springMVC工作流程中屬于視圖解析器 解析視圖這一步。算是視圖解析器的一個插件&#xff0c;作了視圖解析這步的一部…

數據結構與算法--7.樹的基礎知識

文章目錄一. 樹的概念二. 樹的術語三. 樹的種類四. 樹的存儲和表示五. 常見的樹的應用場景一. 樹的概念 二. 樹的術語 三. 樹的種類 四. 樹的存儲和表示 五. 常見的樹的應用場景

運用java 多線程模擬火車售票。。。。

public class Demo01 { public static void main(String[] args) { // TODO Auto-generated method stub //多線程并行時&#xff0c;會出現的問題 //同步&#xff1a; //買火車票&#xff0c;四個窗口A,B,C,D //創建任務 TicketTask task new TicketTask(); //四個窗口A,B,C,…

JQuery validate 各項驗證規則講解

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 使用樣例見&#xff1a;http://blog.csdn.net/jiangyu1013/article/details/56014730 //定義中文消息 var cnmsg { required: “必選字…

數據結構與算法--8.二叉樹的基礎知識

文章目錄一. 二叉樹基本概念二. 二叉樹的性質三. 二叉樹的代碼實現四. 二叉樹的先序、中序、后序遍歷一. 二叉樹基本概念 二. 二叉樹的性質 三. 二叉樹的代碼實現 class Node(object):"""二叉樹節點"""def __init__(self,item):self.elem item…

ZooKeeper(二)ZooKeeper能做什么?

上一節介紹了ZooKeeper的一些基礎知識&#xff0c;這一節主要講ZooKeeper有哪些用途。命名服務&#xff08;Name Service&#xff09; 主要是作為分布式命名服務&#xff0c;通過調用zk的create node api&#xff0c;能夠很容易創建一個全局唯一的path&#xff0c;這個path就可…

jquery vilidate 使用小例

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 // 修改$("#updForm").validate({submitHandler:function(form){new $.flavr({ content : 是否確認修改管理員?,dialog : co…

RedHat Linux 7.3基礎環境搭建

文章目錄1&#xff0e;更改主機名2&#xff0e;關閉selinux3&#xff0e;關閉火墻4&#xff0e;重啟機器5&#xff0e;設置ip6&#xff0e;掛載yum源7&#xff0e;升級openssh8&#xff0e;安全基線9&#xff0e;時區10&#xff0e;時間同步11&#xff0e;安裝Vmtools12&#x…

開源http協議庫curl和wget的區別和使用

curl和wget基礎功能有諸多重疊&#xff0c;如下載等。 在高級用途上的curl由于可自定義各種請求參數所以長于模擬web請求&#xff0c;用于測試網頁交互&#xff08;瀏覽器&#xff09;&#xff1b;wget由于支持ftp和Recursive所以長于下載&#xff0c;用于下載文件&#xff08;…

Spring聲明式事務管理、事務的傳播行為xml配置

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. <tx:method name"insert*" propagation"REQUIRED" />中name的值是ServiceImpl中各個要加入事物管理的方法…

數據結構與算法--9.常見時間復雜度及其之間的關系

文章目錄1.常見時間復雜度2.常見時間復雜度之間的關系1.常見時間復雜度 2.常見時間復雜度之間的關系

CodeIgniter中運用composer安裝依賴包

2019獨角獸企業重金招聘Python工程師標準>>> 基本信息 CodeIgniter 版本&#xff1a;3.1.8Nginx&#xff1a; Tengine/2.1.2 (nginx/1.6.2)MySQL&#xff1a; Ver 14.14 Distrib 5.6.33, for Linux (x86_64) using EditLine wrapperPHP&#xff1a; 5.6.30Zend Engi…

屏幕分辨率

http://cn.screenresolution.org/ 轉載于:https://www.cnblogs.com/qiqi715/p/9363587.html