android 中英文数字符号排版问题,Android AutoWrapTextView中英文排版问题的解决方法...
前言
最近项目有新需求,UED给了个卡券密码的UI样式,如图:
我一看很简单啊,一个TextView解决问题,然后做好以后在模拟器里一看.....
纳尼,这个时候才想起来,TextView 中英文在一起会有排版问题,那怎么解决呢......
思路
刚开始的想法是一个字符一个字符的去绘制,绘制到最右边的临界点就换行绘制,结果实践以后发现不同的字符之间的间距不一样,显示会非常凌乱,又没有什么好的方案解决这个间距问题,所以这个方案pass;单个字符绘制不行那就一行一行绘制,根据View的长度把文本拆分成N行,然后一行一行的绘制。
实现
首先创建一个继承自View的AutoWrapTextView
public class AutoWrapTextView extends View {
}
来看看它的构造方法
public AutoWrapTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
initStyle(context, attrs);
initPaint();
}
init方法里分别调用了initStyle方法和initPaint方法;
initStyle方法主要解析自定义的属性
private void initStyle(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AutoWrapTextViewStyle);
mPaddingLeft = typedArray.getDimensionPixelSize(R.styleable.AutoWrapTextViewStyle_paddingLeft, 0);
mPaddingRight = typedArray.getDimensionPixelSize(R.styleable.AutoWrapTextViewStyle_paddingRight, 0);
mPaddingTop = typedArray.getDimensionPixelSize(R.styleable.AutoWrapTextViewStyle_paddingTop, 0);
mPaddingBottom = typedArray.getDimensionPixelSize(R.styleable.AutoWrapTextViewStyle_paddingBottom, 0);
mTextColor = typedArray.getColor(R.styleable.AutoWrapTextViewStyle_textColor, Color.BLACK);
mTextSize = typedArray.getDimensionPixelSize(R.styleable.AutoWrapTextViewStyle_textSize, 50);
mLineSpacingExtra = typedArray.getInteger(R.styleable.AutoWrapTextViewStyle_lineSpacingExtra, 7);
typedArray.recycle();
}
属性名含义都很明显不用过多解释,initPaint方法就是初始化一个文本画笔
private void initPaint() {
mTextPaint = new TextPaint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(mTextSize);
mTextPaint.setColor(mTextColor);
mTextPaint.setTextAlign(Paint.Align.LEFT);
}
接下来我们看看设置文本的方法setText方法
public void setText(String text) {
if (TextUtils.isEmpty(text)) return;
//把文本转换成Char数组
mTextCharArray = text.toCharArray();
requestLayout();
}
首先把文本转换成Char数组,然后循环数组把整个文本拆分成N行文本,下面来看看核心方法splitText方法
private void splitText(int heightMode) {
if (mTextCharArray == null) return;
mSplitTextList = new ArrayList<>();
mSingleTextWidth = getMeasuredWidth() - mPaddingLeft - mPaddingRight;
int currentSingleTextWidth = 0;
StringBuffer lineStringBuffer = new StringBuffer();
for (int i = 0, length = mTextCharArray.length; i < length; i++) {
char textChar = mTextCharArray[i];
currentSingleTextWidth += getSingleCharWidth(textChar);
if (currentSingleTextWidth > mSingleTextWidth) {
mSplitTextList.add(lineStringBuffer.toString());
lineStringBuffer = new StringBuffer();
currentSingleTextWidth = 0;
i--;
} else {
lineStringBuffer.append(textChar);
if (i == length - 1) mSplitTextList.add(lineStringBuffer.toString());
}
}
int textHeight = 0;
mSplitTextRectArray = new Rect[mSplitTextList.size()];
for (int m = 0, length = mSplitTextList.size(); m < length; m++) {
String lineText = mSplitTextList.get(m);
Rect lineTextRect = new Rect();
mTextPaint.getTextBounds(lineText, 0, lineText.length(), lineTextRect);
if (heightMode == MeasureSpec.AT_MOST) {
textHeight += (lineTextRect.height() + mLineSpacingExtra);
if (m == length - 1) {
textHeight = textHeight + mPaddingBottom + mPaddingTop;
}
} else {
if (textHeight == 0)
textHeight = getMeasuredHeight();
}
mSplitTextRectArray[m] = lineTextRect;
}
setMeasuredDimension(getMeasuredWidth(), textHeight);
}
首先创建一个属性名为mSplitTextList的List集合用来存放拆分的文本;
mSingleTextWidth 为单行文本显示的宽度;
currentSingleTextWidth 为当前一行累计计算的宽度;
然后开始循环Char数组,getSingleCharWidth方法就是计算单个Char的宽度;
如果currentSingleTextWidth 小于 mSingleTextWidth 就把Char添加到lineStringBuffer 当中,如果是最后一个Char就直接把lineStringBuffer添加到mSplitTextList集合当中
如果currentSingleTextWidth 大于 mSingleTextWidth,就把lineStringBuffer添加到mSplitTextList集合当中,重新给lineStringBuffer赋值,currentSingleTextWidth 归0;
循环结束以后拆分好的文本就都添加到mSplitTextList集合当中了。
拆分完成以后循环mSplitTextList集合,得到每一行文本的Rect值,绘制文本的时候会用到,然后设置View的宽高。
接下来就是绘制方法drawText
public void drawText(Canvas canvas) {
if (mSplitTextList == null || mSplitTextList.size() == 0) return;
int marginTop = getTopTextMarginTop();
for (int m = 0, length = mSplitTextList.size(); m < length; m++) {
String lineText = mSplitTextList.get(m);
canvas.drawText(lineText, mPaddingLeft, marginTop, mTextPaint);
marginTop += (mSplitTextRectArray[m].height() + mLineSpacingExtra);
}
}
首先得到第一行文本距离顶部的高度marginTop,然后循环文本绘制每一行文本内容。
效果图
我们来看下最后的效果
结束语
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
android 中英文数字符号排版问题,Android AutoWrapTextView中英文排版问题的解决方法...相关推荐
- java数字时钟代码,Android自定义数字时钟代码,android自定义时钟,package jp.t
Android自定义数字时钟代码,android自定义时钟,package jp.tpackage jp.tsmsogn.digitalclock;import java.util.Calendar; ...
- Linux 2.6.32-279.el6.x86_64 ANDROID SDK碰到”LIBC.SO.6: VERSION `GLIBC_2.14′ NOT FOUND”的解决方法(1)
1.执行locate libc.so.6找到库的位置; /lib64/libc.so.6 2.查看系统已支持的版本: strings /lib64/libc.so.6 | grep GLIB ...
- android线程改变布局,Android线程中设置控件的值提示报错的解决方法
本文实例讲述了Android线程中设置控件的值提示报错的解决方法.分享给大家供大家参考,具体如下: 在Android线程中设置控件的值一般会与Handler联合使用,如下: package com.y ...
- Android popupwindow 失去焦点或者点击空白区域时消失的解决方法
Android popupwindow 失去焦点或者点击空白区域时消失的解决方法 参考文章: (1)Android popupwindow 失去焦点或者点击空白区域时消失的解决方法 (2)https: ...
- Android开发中遇到的问题(四)——Android中WARNING: Application does not specify an API level requirement!的解决方法
Android开发中遇到的问题(四)--Android中WARNING: Application does not specify an API level requirement!的解决方法 参考文 ...
- Android 软键盘弹出时把原来布局顶上去的解决方法
Android 软键盘弹出时把原来布局顶上去的解决方法 参考文章: (1)Android 软键盘弹出时把原来布局顶上去的解决方法 (2)https://www.cnblogs.com/Joanna-Y ...
- Android联网报错:Cleartext HTTP traffic to XXXXX not permitted的解决方法
Android联网报错:Cleartext HTTP traffic to XXXXX not permitted的解决方法 Android联网报错:Cleartext HTTP traffic to ...
- android编程权威指南 的PhotoGallery项目Flickr 不能访问的替代解决方法
android编程权威指南 的PhotoGallery项目Flickr 不能访问的替代解决方法 参考: <<android编程权威指南(第2版)>>的PhotoGallery项 ...
- html中英文混排,EndNote中英文混排时et al和等的3种解决方法 | 科研动力
EndNote对于英文文献的处理很出色,但是对于中文文献的处理就有点别扭,尤其是中英文文献混排时更是不爽.木有关系,EndNote的强大这处之一就是可以驯服和调教.下面介绍3种如何处理中英文混排时et ...
- c# 导出excel 数字太长而显示为科学计数法的解决方法
c# 导出excel 数字太长而显示为科学计数法的解决方法 <td style=\"vnd.ms-excel.numberformat:@\"> {0}</td& ...
最新文章
- 【跟着我们学Golang】之异常处理
- vagrant 本地添加box 支持带版本号
- SpringBoot配置Druid
- 【FBA】SharePoint 2013自定义Providers在基于表单的身份验证(Forms-Based-Authentication)中的应用...
- react 子传参父_React 子组件向父组件传值的方法
- 是Excel的图,不!是R的图
- html中css如何引用自定义字体 - 案例篇
- react留言功能准备一
- linux 查看hadoop命令大全,linux下hadoop集群常用命令
- SaltStack 修复 Stack minion中的提权漏洞 (CVE-2020-28243)
- java二维码生成代码_java快速开发平台功能特点之代码生成器
- 【转载】一个c程序在执行main函数之前和main之后都做了那些事情
- 大数据分析平台建设项目需求报告与技术方案
- 大数据在国外发展现状研究学习笔记
- 解决笔记本显示器屏幕亮度无法调节情况
- fixdown down,一个时代的终结。
- Reveal Effect(揭露效果)低版本兼容
- 基于微信小程序开发的在线答题系统
- 最详细教程:Zotero和Better BibTeX安装,以及如何在R markdown中引用文献
- NX二次开发(C#)-UIStyler-ListBox(列表框)的应用