android中的textview控件默认是做不到两端对齐的,都是左对齐。可能的原因是安卓默认数字、字母不能为第一行以后每行的开头字符,因为数字、字母为半角字符,还有就是文字中的英文字符占用1个字节,而一个汉字占用两个字节。下面我就介绍下实现两端对齐的原理:
- 1、测量一个中文汉字所占用的宽度
- 2、根据textview的宽度和一个汉字所占用的宽度以及字符之间的间隔计算出总行数。
- 3、根据padding和margin以及行高计算出textview的总高度。
- 4、绘制每一行的每一个字符
效果如下:
具体代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
package com.wedroid.framework.module.ui; import android.content.context; import android.graphics.canvas; import android.graphics.paint; import android.text.textpaint; import android.text.textutils; import android.util.attributeset; import android.view.viewgroup.marginlayoutparams; import android.view.viewtreeobserver.onpredrawlistener; import android.widget.textview; public class wedroidaligntextview extends textview { private boolean first = true ; public wedroidaligntextview(context context, attributeset attrs, int defstyle) { super (context, attrs, defstyle); getviewtreeobserver().addonpredrawlistener( new onpredrawlistener() { @override public boolean onpredraw() { inittextinfo(); return true ; } }); } public wedroidaligntextview(context context, attributeset attrs) { this (context, attrs, 0 ); } public wedroidaligntextview(context context) { this (context, null , 0 ); } private float textsize; private float textlineheight; private int top; private int y; private int lines; private int bottom; private int right; private int left; private int linedrawwords; private char [] textchararray; private float singlewordwidth; private float linespacingextra; public void inittextinfo() { textsize = gettextsize(); textlineheight = getlineheight(); left = 0 ; right = getright(); y = gettop(); // 要画的宽度 int drawtotalwidth = right - left; string text = gettext().tostring(); if (!textutils.isempty(text) && first) { textchararray = text.tochararray(); textpaint mtextpaint = new textpaint(paint.anti_alias_flag); mtextpaint.density = getresources().getdisplaymetrics().density; mtextpaint.settextsize(textsize); // 一个单词的的宽度 singlewordwidth = mtextpaint.measuretext( "一" ) + linespacingextra; // 一行可以放多少个字符 linedrawwords = ( int ) (drawtotalwidth / singlewordwidth); int length = textchararray.length; lines = length / linedrawwords; if ((length % linedrawwords) > 0 ) { lines = lines + 1 ; } first = false ; marginlayoutparams layoutparams = (marginlayoutparams) getlayoutparams(); int totalheight = ( int ) (lines*textlineheight+textlineheight* 2 + getpaddingbottom()+getpaddingtop()+layoutparams.bottommargin+layoutparams.topmargin); setheight(totalheight); } } @override protected void ondraw(canvas canvas) { bottom = getbottom(); int drawtotalline = lines; if (maxline!= 0 &&drawtotalline>maxline){ drawtotalline = maxline; } for ( int i = 0 ; i < drawtotalline; i++) { try { int length = textchararray.length; int mleft = left; // 第i+1行开始的字符index int startindex = (i * 1 ) * linedrawwords; // 第i+1行结束的字符index int endtextindex = startindex + linedrawwords; if (endtextindex > length) { endtextindex = length; y += textlineheight; } else { y += textlineheight; } for (; startindex < endtextindex; startindex++) { char c = textchararray[startindex]; // if (c == ' ') { // c = '\u3000'; // } else if (c < '\177') { // c = (char) (c + 65248); // } canvas.drawtext(string.valueof(c), mleft, y, getpaint()); mleft += singlewordwidth; } } catch (exception e) { e.printstacktrace(); } } } int maxline; public void setmaxlines( int max){ this .maxline = max; } public void setlinespacingextra( int linespacingextra){ this .linespacingextra = linespacingextra; } /** * 判断是否为中文 * @return */ public static boolean containchinese(string string){ boolean flag = false ; for ( int i = 0 ; i < string.length(); i++) { char c = string.charat(i); if ((c >= 0x4e00 ) && (c <= 0x9fa5 )) { flag = true ; } } return flag; } public static string todbc(string input) { // 导致textview异常换行的原因:安卓默认数字、字母不能为第一行以后每行的开头字符,因为数字、字母为半角字符 // 所以我们只需要将半角字符转换为全角字符即可 char c[] = input.tochararray(); for ( int i = 0 ; i < c.length; i++) { if (c[i] == ' ' ) { c[i] = '\u3000' ; } else if (c[i] < '\177' ) { c[i] = ( char ) (c[i] + 65248 ); } } return new string(c); } } |
希望本文所述对大家学习android程序设计有所帮助。