TextView是个特别基础的Android控件,只要有文本基本就少不了它。但是最近在项目开发的过程中我发现TextView存在很多局限性,其中最令我头疼的就是TextView文本排版方面的问题。我们都知道在word中文字对齐方式有靠左、靠右、居中、分散对齐等,但是TextView中就偏偏没有分散对齐这个属性设置。这就导致了TextView中一段文字会出现右边参差不齐的问题,中文由于每个字等宽看起来还不是特别糟糕,英文看起来就比较过分了。

为了解决这个问题,一个常用的解决方法是在TextView内使用html来实现文本样式的设定,或者干脆放弃TextView而使用WebView来实现。但是,凡事都应该敢于解决问题,而不是回避问题,我相信即使仅用TextView一样是可以实现,后来我发现stackoverflow上有个回答提供了一种思路,我按照这种思路果然实现了TextView文本的分散对齐。原地址链接如下:http://stackoverflow.com/questions/8644649/full-text-justification-in-android/17807828#17807828,原回答有点问题,导致没人点赞,亏我还能发现它。

以下是我的实现过程:

MainActivity中:

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
width = dm.widthPixels;
//根据屏幕调整文字大小
mArticleTextView.setLineSpacing(0f, 1.5f);
mArticleTextView.setTextSize(8*(float)width/320f);
//设置TextView
mArticleTextView.setText("TextView需要显示的文本内容"); TextJustification.justify(mArticleTextView,mArticleTextView.getWidth());

首先设置TextView的显示字体大小和文本内容,这里设置字体大小根据屏幕尺寸调整。然后调用自定义的类Textustification中的justify方法来实现TextView的分散对齐,两个参数分别是TextView控件以及控件的宽度。

自定义的类TextJustification内容如下:

import java.util.ArrayList;

import android.graphics.Paint;
import android.text.TextUtils;
import android.widget.TextView;
import android.widget.TextView.BufferType; public class TextJustification { public static void justify(TextView textView, float contentWidth) {
String text=textView.getText().toString();
String tempText;
String resultText = "";
Paint paint=textView.getPaint(); ArrayList<String> paraList = new ArrayList<String>();
paraList = paraBreak(text);
for(int i = 0; i<paraList.size(); i++) {
ArrayList<String> lineList=lineBreak(paraList.get(i).trim(),paint,contentWidth);
tempText = TextUtils.join(" ", lineList).replaceFirst("\\s*", "");
resultText += tempText.replaceFirst("\\s*", "") + "\n";
} textView.setText(resultText);
}
//分开每个段落
public static ArrayList<String> paraBreak(String text, TextView textview) {
ArrayList<String> paraList = new ArrayList<String>();
String[] paraArray = text.split("\\n+");
for(String para:paraArray) {
paraList.add(para);
}
return paraList;
} //分开每一行,使每一行填入最多的单词数
private static ArrayList<String> lineBreak(String text, Paint paint, float contentWidth){
String [] wordArray=text.split("\\s");
ArrayList<String> lineList = new ArrayList<String>();
String myText=""; for(String word:wordArray){
if(paint.measureText(myText+" "+word)<=contentWidth)
myText=myText+" "+word;
else{
int totalSpacesToInsert=(int)((contentWidth-paint.measureText(myText))/paint.measureText(" "));
lineList.add(justifyLine(myText,totalSpacesToInsert));
myText=word;
}
}
lineList.add(myText);
return lineList;
}
//已填入最多单词数的一行,插入对应的空格数直到该行满
private static String justifyLine(String text,int totalSpacesToInsert){
String[] wordArray=text.split("\\s");
String toAppend=" "; while((totalSpacesToInsert)>=(wordArray.length-1)){
toAppend=toAppend+" ";
totalSpacesToInsert=totalSpacesToInsert-(wordArray.length-1);
}
int i=0;
String justifiedText="";
for(String word:wordArray){
if(i<totalSpacesToInsert)
justifiedText=justifiedText+word+" "+toAppend; else
justifiedText=justifiedText+word+toAppend; i++;
} return justifiedText;
} }

这个类完成了TextView内部文字的排版工作,主要分3个步骤:
1、将一篇文章按段落分成若干段(如果只有一段可以略去该步骤);

2、将每一段的文字拆分成各个单词,然后根据控件长度确定每一行最多可以填入的单词数,并且算出排满该行还需要填入几个空格。

3、填入空格。

注意代码中用到了一些正则表达式进行文章内容操作,若不清楚可以自行搜索含义。

这样就完成了TextView内部文字分散对齐的排版过程。总结一下,这样操作还是有点蛋疼的,虽然不算复杂,但还是对文本内容进行了完全的重新处理;并且仅是使用了已有的文本和空格数来实现对齐,并不是严格的分散对齐。但不管怎么说,终究是用TextView自身的操作来实现了,并且效果还算不错。

[Android]TextView实现分散对齐(两端对齐)的更多相关文章

  1. 转-安卓中实现两端对齐,中间fill_parent的方法

    安卓中实现两端对齐,中间fill_parent的方法 Java代码:   <?xml version="1.0″ encoding="utf-8″?> <Line ...

  2. 【原】css实现两端对齐的3种方法

    说到两端对齐,大家并不陌生,在word.powerpoint.outlook等界面导航处,其实都有一个两端对齐(分散对齐)的按钮,平时使用的也不多,我们更习惯与左对齐.居中对齐.右对齐的方式来对齐页面 ...

  3. css实现两端对齐的3种方法

    两端对齐在移动端非常见,说到两端对齐,大家并不陌生,在word.powerpoint.outlook等界面导航处,其实都有一个两端对齐(分散对齐)的按钮,平时使用的也不多,我们更习惯与左对齐.居中对齐 ...

  4. 实现css两端对齐

    如何实现css的两端对齐功能? 最近做项目遇到这种情况,如图所示: input左边框的用户,旧密码,新密码,确认密码无法对齐,样式很丑. 解决办法: 找到对应的类名,加上:text-align:jus ...

  5. 完美 全兼容 解决 文字两端对齐 justify 中文姓名对齐

    text-align:justify; 所有浏览器都支持,text-justify之类的却只有IE支持,就不要考虑了. justify我的理解,使元素内部的子元素两端对齐,子元素当然只能是inline ...

  6. CSS3 justify 文本两端对齐

    浏览器参照基准:Firefox4 and Later, Chrome5 and Later, Safari5 and Later, Opera10.53 and Later, IE5.5 and La ...

  7. HTML如何让文本两端对齐

    <p style="text-align:justify; text-justify:inter-ideograph;>日本驻华大使丹羽宇一郎:日中关系比夫妻还紧密日本驻华大使丹 ...

  8. 前端排版-使用inline-block且两端对齐

    那天排遇到这样一个页面,每个logo紧挨着,而且两端对齐.尼玛,没招啊~ 今天终于找到了解决办法: <!DOCTYPE html> <html> <head> &l ...

  9. css文字两端对齐

    css文字两端对齐 text-align:Justify(火狐); text-justify:inter-ideograph(IE) text-justify(IE) 基本语法 text-justif ...

随机推荐

  1. 【hihocoder 1562】⼩Hi的钟表

    [链接]点击打开链接 [题意] 在这里写题意 [题解] 时针每过1分钟转0.5°. (360/(12*60)) 分钟每过1分钟转6° (360/60); 根据这个就能算出时针和分针的角度之差了. [错 ...

  2. JQuery EasyUI Combobox 实现省市二级联动菜单

    //编辑改动或新增页面联动能够这样写 jQuery(function(){ // 省级 $('#province').combobox({ valueField:'itemvalue', //值字段 ...

  3. python3 登录验证小程序,同一用户输错三次密码,锁定账户

    ''' 让用户输入用户名密码 认证成功后显示欢迎信息用户3次认证失败后,退出程序,再次启动程序尝试登录时,还是锁定状态''' # !/usr/bin/env python # -*- coding:u ...

  4. WPF 支持分组互斥的 RadioButton 式单选菜单

    扩展 MenuItem 为同组互斥的 RadioMenuItem,并且将对勾符号修改为圆点. http://stackoverflow.com/a/35692688/5972372 这个问题下还有其他 ...

  5. [React] Style a React component with styled-components

    In this lesson, we remove the mapping between a React component and the styles applied to it via cla ...

  6. poj 2240 floyd算法

    Arbitrage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17349   Accepted: 7304 Descri ...

  7. js进阶 12 jquery事件汇总

    js进阶 12 jquery事件汇总 一.常用事件 页面载入事件 ready() 文档就绪事件(当 HTML 文档就绪可用时) 鼠标事件 click() 触发.或将函数绑定到指定元素的 click 事 ...

  8. OC学习篇之---协议的概念和用法

    这一篇文章我们在来看一下OC中协议的概念以及用法,协议也是OC中的一个重点,Foundation框架以及我们后面在写代码都会用到. OC中的协议就是相当于Java中的接口(抽象类),只不过OC中的名字 ...

  9. 【u252】泽泽在巴西

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 泽泽帮助了英国某街道尽量减少酸雨的伤害,街道办主任非常感激他,就把他领到一扇门前,告诉他这扇门能通往好 ...

  10. unity 3d开发的大型网络游戏

    unity 3d开发的大型网络游戏 一.总结 1.unity的官网上面应该有游戏列表 2.unity3D是很好的3d游戏引擎,也支持2d,也能做很多画面精良的3A级游戏 3.范围:电脑游戏,手机游戏, ...