一停巷、繪制文本
在Canvas中繪制文本耍攘,使用前面文章的坐標(biāo)系
1、drawText的幾種方法
public void drawText (String text, float x, float y, Paint paint)
public void drawText (String text, int start, int end, float x, float y, Paint paint)
public void drawText (CharSequence text, int start, int end, float x, float y, Paint paint)
public void drawText (char[] text, int index, int count, float x, float y, Paint paint)
public void drawText (String text, float x, float y, Paint paint)
x 畔勤、 y軸表示繪制文本左下角到坐標(biāo)
mPaint.setColor(Color.RED);
mPaint.setTextSize(50);
String string="HeDan";
canvas.drawText(string,0,0,mPaint);
public void drawText (String text, int start, int end, float x, float y, Paint paint)
繪制一部分Text,start表示從第幾個字符開始蕾各,end表示第幾個字符之前結(jié)束
//public void drawText (String text, int start, int end, float x, float y, Paint paint)
canvas.drawText(string,0,3,0,0,mPaint);
public void drawText (CharSequence text, int start, int end, float x, float y, Paint paint)使用CharSequence繪制,方法庆揪,效果同上
public void drawText (char[] text, int index, int count, float x, float y, Paint paint)使用字符數(shù)組繪制式曲,方法,效果同上
2缸榛、drawPosText
給文本中到每個字符都設(shè)定一個坐標(biāo)吝羞,不推薦使用
3、drawTextOnPath
通過Path進(jìn)行文本繪制内颗,path是一個比較重要且有趣的東西钧排,在之后涉及知識中會進(jìn)行分析。
Path path = new Path();
path.lineTo(0,200);
canvas.drawTextOnPath(string,path,100,100,mPaint);
這里簡單寫一個均澳,path為一條從原點到(0,200)的直線恨溜,水平偏移量、垂直偏移量都設(shè)置為100,效果如下:
二找前、文本居中
1糟袁、單行文本居中
a、 public void getTextBounds(String text, int start, int end, Rect bounds)
通過Rect獲取文本寬度和高度躺盛,方法如下
Rect rect = new Rect();
mPaint.getTextBounds(string,0,string.length(),rect);
int width = rect.width();//文本寬度
int height = rect.height();//文本高度
b项戴、getFontMetrics(),getFontMetricsInt()用于返回字符串的測量,而兩個方法的區(qū)別就是返回值得類型颗品。返回值一共五個屬性:
- Top: baseline到文本頂部的最大的距離
- Ascent:baseline到文本頂部到推薦距離
- Descent:baseline到文本底部到推薦距離
- Bottom:baseline到文本底部到最大距離
- Leading:兩行文本之間推薦到額外距離肯尺,一般為0(推薦不考慮)
在Android的坐標(biāo)系中沃缘,向下為Y軸正方向,向上為Y軸負(fù)方向则吟,所部baseling之上到Top與Ascent都是負(fù)數(shù)槐臀,而baselin之下到Descent、Bottom都是正數(shù)氓仲。如果要讓字符串在垂直方向上居中水慨,則需要在縱坐標(biāo)上增加Asecent絕對值與descent的差。
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
float textHeight=(-fontMetrics.ascent-fontMetrics.descent)/2;
canvas.drawText(string,0,textHeight,mPaint);
c敬扛、setTextAlign可以設(shè)置畫筆繪制文本到對齊方式晰洒,選擇center即可完成文本到水平居中
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
float textHeight=(-fontMetrics.ascent-fontMetrics.descent)/2;
mPaint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(string,0,textHeight,mPaint);
d、measureText可以測量文本的寬度啥箭,即橫向長度谍珊,這樣也可以來完成居中設(shè)置,但在這之前急侥,需要恢復(fù)文本對齊方式至默認(rèn)設(shè)置(居左)砌滞。
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
float textHeight=(-fontMetrics.ascent-fontMetrics.descent)/2;
float textWidth = mPaint.measureText(string);
canvas.drawText(string,-textWidth/2,textHeight,mPaint);
效果同上C。
2坏怪、多行文本居中
有設(shè)定好的字符串?dāng)?shù)組贝润,畫筆,畫布铝宵,坐標(biāo)點
- 1打掘、drawText每次只能繪制一行,通過for循環(huán)
- 2鹏秋、字符串?dāng)?shù)組大于1時尊蚁,每個字符到高度應(yīng)該為-top+bottom,總高度為length*(-top+bottom)
- 3、偏移量就等于length*(-top+bottom)/2-bottom
- 4侣夷、如果順序向上(Y負(fù)方向)排列到話枝誊,那么第i個字符串到高度就是-(length-i-1)*(-top+bottom)
- 5、每個字符串高度減去偏移量惜纸,就應(yīng)該是每個字符串到baseline的y坐標(biāo)
詳細(xì)代碼
private void textCenter(String [] strings, Paint paint, Canvas canvas, Point point,Paint.Align aligin){
paint.setTextAlign(aligin);
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
float top=fontMetrics.top;
float bottom=fontMetrics.bottom;
int length=strings.length;
float total=(length-1)*(-top+bottom)+(-fontMetrics.ascent+fontMetrics.descent);
float offset=total/2-bottom;
for(int i=0;i<length;i++){
float yAxis=-(length-i-1)*(-top+bottom)+offset;
canvas.drawText(strings[i]+"",point.x,point.y+yAxis,paint);
}
}
偏移量取值的變化叶撒,是因為在字符串的首尾兩個字符串,需要把top改成ascent耐版,bottom改成descent祠够。通過設(shè)置畫筆來完成橫向的居中,居左粪牲,居右古瓤。
使用代碼
String[] striings={"HeDan","是","一","個","好","學(xué)","生"};
//String[] striings={"床前明月光,","疑是地上霜。","舉頭望明月落君,","低頭思故鄉(xiāng)穿香。"};
Point point=new Point(0,0);
//textCenter(striings,mPaint,canvas,point, Paint.Align.CENTER);
textCenter(striings,mPaint,canvas,point, Paint.Align.LEFT);
3、多列文本
- 1绎速、一個字符串?dāng)?shù)組
- 2皮获、每個字符數(shù)組中獲取最寬到字符寬度我字符數(shù)組的寬度
- 3、計算數(shù)組x坐標(biāo)纹冤,再掉用之前多行文本居中到代碼
居右詳細(xì)代碼
private void textCenter(char[] strings, Paint paint, Canvas canvas, Point point,Paint.Align aligin){
paint.setTextAlign(aligin);
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
float top=fontMetrics.top;
float bottom=fontMetrics.bottom;
int length=strings.length;
float total=(length-1)*(-top+bottom)+(-fontMetrics.ascent+fontMetrics.descent);
float offset=total/2-bottom;
for(int i=0;i<length;i++){
float yAxis=-(length-i-1)*(-top+bottom)+offset;
canvas.drawText(strings[i]+"",point.x,point.y+yAxis,paint);
}
}
private void rowTextRight(String[] strings,Paint paint,Canvas canvas,Point point){
int length = strings.length;
float len ,newLen;
float total=0;
for(int j=0;j<length;j++){
char[] chars = strings[j].toCharArray();
len=paint.measureText(chars[0]+"");
for (int i=1; i<chars.length; i++){
newLen = mPaint.measureText(chars[i]+"");
len = Math.max(newLen,len);
}
point.x=point.x-(int)total;
textCenter(chars,paint,canvas,point, Paint.Align.RIGHT);
point.x = point.x + (int) total;
total = total+len;
}
}
使用代碼
String[] striings={"鵝歇攻,鵝乌助,鵝缠犀,","曲項向天歌乳讥,","白毛浮綠水,","紅掌撥清波知残,"};
Point point=new Point(0,0);
rowTextRight(striings,mPaint,canvas,point);
居左詳細(xì)代碼
private void rowTextLeft(String[] strings,Paint paint,Canvas canvas,Point point){
int length = strings.length;
float len ,newLen;
float total=0;
for(int j=0;j<length;j++){
char[] chars = strings[j].toCharArray();
len=paint.measureText(chars[0]+"");
for (int i=1; i<chars.length; i++){
newLen = mPaint.measureText(chars[i]+"");
len = Math.max(newLen,len);
}
point.x=point.x+(int)total;
textCenter(chars,paint,canvas,point, Paint.Align.LEFT);
point.x = point.x - (int) total;
total = total+len;
}
}
居中詳細(xì)代碼
private void rowTextCenter(String[] strings,Paint paint,Canvas canvas,Point point){
int length = strings.length;
float len ,newLen;
float total=0;
for(int j=0;j<length;j++){
char[] chars = strings[j].toCharArray();
len=paint.measureText(chars[0]+"");
for (int i=1; i<chars.length; i++){
newLen = mPaint.measureText(chars[i]+"");
len = Math.max(newLen,len);
}
total = total+len;
}
for(int j=0;j<length;j++){
char[] chars = strings[j].toCharArray();
len=paint.measureText(chars[0]+"");
for (int i=1; i<chars.length; i++){
newLen = mPaint.measureText(chars[i]+"");
len = Math.max(newLen,len);
}
if(j==0){
point.x=(int)-(total-len)/2;
}
textCenter(chars,paint,canvas,point, Paint.Align.CENTER);
point.x=point.x+(int)len;
}
}
```
4靠瞎、文本自動換行居中
自動換行在Android 自定義View 一(初體驗onDraw(),自定義屬性,onMeasue()方法,測量換行)這里在介紹一個系統(tǒng)到方法:
StaticLayout,可以設(shè)置寬度,當(dāng)前行文本超過此寬度后求妹,進(jìn)行自動換行较坛,提供提供ALIGN_CENTER(居中)、ALIGN_NORMAL(標(biāo)準(zhǔn))扒最、ALIGN_OPPOSITE(與標(biāo)準(zhǔn)相反)三種對齊方式
詳細(xì)代碼:
private void textCenter(String string, TextPaint textPaint, Canvas canvas, Point point, int width, Layout.Alignment align,float spacingmult,float spacingadd,boolean includepad){
StaticLayout staticLayout = new StaticLayout(string,textPaint,width, align,spacingmult,spacingadd,includepad);
canvas.save();
canvas.translate(-staticLayout.getWidth()/2+point.x,-staticLayout.getHeight()/2+point.y);
staticLayout.draw(canvas);
canvas.restore();
}
使用方法
String mString="HeDan是一個好學(xué)生";
TextPaint tp = new TextPaint();
tp.setColor(Color.BLUE);
tp.setStyle(Paint.Style.FILL);
Point point=new Point(0,0);
tp.setTextSize(50);
textCenter(mString,tp,canvas,point,200,Layout.Alignment.ALIGN_CENTER,1.5f,0,false);
下面貼出學(xué)習(xí)源碼:
public class MultipleText extends View {
private Paint mPaint;
private float pWidth;
private float pHeight;
private int mWidth;
private int mHeight;
public MultipleText(Context context) {
this(context, null);
}
public MultipleText(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MultipleText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
/**
* 初始化畫筆
*/
private void initPaint() {
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);//設(shè)置畫筆填充
mPaint.setAntiAlias(true);//抗鋸齒
mPaint.setColor(Color.parseColor("#52adff"));//設(shè)置畫筆顏色
}
;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(mWidth / 2, mHeight / 2);
mPaint.setStrokeWidth(10);//設(shè)置原點寬度
canvas.drawPoint(0, 0, mPaint);//繪制原點
canvas.drawPoints(new float[]{pWidth, 0, 0, pHeight, -pWidth, 0, 0, -pHeight}, mPaint);//繪制邊緣點*/
mPaint.setStrokeWidth(1);//重新設(shè)置畫筆到寬度
canvas.drawLine(-pWidth, 0, pWidth, 0, mPaint);//繪制X軸
canvas.drawLine(0, -pHeight, 0, pHeight, mPaint);//繪制Y軸
mPaint.setStrokeWidth(3);//設(shè)置箭頭寬度
canvas.drawLines(new float[]{pWidth, 0, pWidth * 0.95f, -pWidth * 0.05f, pWidth, 0, pWidth * 0.95f, pWidth * 0.05f}, mPaint);//X軸箭頭
canvas.drawLines(new float[]{0, pHeight, -pHeight * 0.05f, pHeight * 0.95f, 0, pHeight, pHeight * 0.05f, pHeight * 0.95f}, mPaint);//Y軸箭頭
mPaint.setColor(Color.RED);
mPaint.setTextSize(50);
String string="HeDan";
//public void drawText (String text, float x, float y, Paint paint)
//canvas.drawText(string,0,0,mPaint);
//public void drawText (String text, int start, int end, float x, float y, Paint paint)
// canvas.drawText(string,0,3,0,0,mPaint);
/* Path path=new Path();
path.lineTo(0,200);
canvas.drawTextOnPath(string,path,100,100,mPaint);
Rect rect = new Rect();
mPaint.getTextBounds(string,0,string.length(),rect);
int width = rect.width();//文本寬度
int height = rect.height();//文本高度*/
/* Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
float textHeight=(-fontMetrics.ascent-fontMetrics.descent)/2;
float textWidth = mPaint.measureText(string);
canvas.drawText(string,-textWidth/2,textHeight,mPaint);*/
/* String[] striings={"鵝,鵝华嘹,鵝吧趣,","曲項向天歌,","白毛浮綠水耙厚,","紅掌撥清波强挫,"};
Point point=new Point(0,0);
textCenter(striings,mPaint,canvas,point, Paint.Align.LEFT);
rowTextCenter(striings,mPaint,canvas,point);*/
String mString="HeDan是一個好學(xué)生";
TextPaint tp = new TextPaint();
tp.setColor(Color.BLUE);
tp.setStyle(Paint.Style.FILL);
Point point=new Point(0,0);
tp.setTextSize(50);
textCenter(mString,tp,canvas,point,200,Layout.Alignment.ALIGN_CENTER,1.5f,0,false);
}
private void textCenter(String [] strings, Paint paint, Canvas canvas, Point point,Paint.Align aligin){
paint.setTextAlign(aligin);
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
float top=fontMetrics.top;
float bottom=fontMetrics.bottom;
int length=strings.length;
float total=(length-1)*(-top+bottom)+(-fontMetrics.ascent+fontMetrics.descent);
float offset=total/2-bottom;
for(int i=0;i<length;i++){
float yAxis=-(length-i-1)*(-top+bottom)+offset;
canvas.drawText(strings[i],point.x,point.y+yAxis,paint);
}
}
private void textCenter(char[] strings, Paint paint, Canvas canvas, Point point,Paint.Align aligin){
paint.setTextAlign(aligin);
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
float top=fontMetrics.top;
float bottom=fontMetrics.bottom;
int length=strings.length;
float total=(length-1)*(-top+bottom)+(-fontMetrics.ascent+fontMetrics.descent);
float offset=total/2-bottom;
for(int i=0;i<length;i++){
float yAxis=-(length-i-1)*(-top+bottom)+offset;
canvas.drawText(strings[i]+"",point.x,point.y+yAxis,paint);
}
}
private void rowTextRight(String[] strings,Paint paint,Canvas canvas,Point point){
int length = strings.length;
float len ,newLen;
float total=0;
for(int j=0;j<length;j++){
char[] chars = strings[j].toCharArray();
len=paint.measureText(chars[0]+"");
for (int i=1; i<chars.length; i++){
newLen = mPaint.measureText(chars[i]+"");
len = Math.max(newLen,len);
}
point.x=point.x-(int)total;
textCenter(chars,paint,canvas,point, Paint.Align.RIGHT);
point.x = point.x + (int) total;
total = total+len;
}
}
private void rowTextLeft(String[] strings,Paint paint,Canvas canvas,Point point){
int length = strings.length;
float len ,newLen;
float total=0;
for(int j=0;j<length;j++){
char[] chars = strings[j].toCharArray();
len=paint.measureText(chars[0]+"");
for (int i=1; i<chars.length; i++){
newLen = mPaint.measureText(chars[i]+"");
len = Math.max(newLen,len);
}
point.x=point.x+(int)total;
textCenter(chars,paint,canvas,point, Paint.Align.LEFT);
point.x = point.x - (int) total;
total = total+len;
}
}
private void rowTextCenter(String[] strings,Paint paint,Canvas canvas,Point point){
int length = strings.length;
float len ,newLen;
float total=0;
for(int j=0;j<length;j++){
char[] chars = strings[j].toCharArray();
len=paint.measureText(chars[0]+"");
for (int i=1; i<chars.length; i++){
newLen = mPaint.measureText(chars[i]+"");
len = Math.max(newLen,len);
}
total = total+len;
}
for(int j=0;j<length;j++){
char[] chars = strings[j].toCharArray();
len=paint.measureText(chars[0]+"");
for (int i=1; i<chars.length; i++){
newLen = mPaint.measureText(chars[i]+"");
len = Math.max(newLen,len);
}
if(j==0){
point.x=(int)-(total-len)/2;
}
textCenter(chars,paint,canvas,point, Paint.Align.CENTER);
point.x=point.x+(int)len;
}
}
private void textCenter(String string, TextPaint textPaint, Canvas canvas, Point point, int width, Layout.Alignment align,float spacingmult,float spacingadd,boolean includepad){
StaticLayout staticLayout = new StaticLayout(string,textPaint,width, align,spacingmult,spacingadd,includepad);
canvas.save();
canvas.translate(-staticLayout.getWidth()/2+point.x,-staticLayout.getHeight()/2+point.y);
staticLayout.draw(canvas);
canvas.restore();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
pWidth = mWidth / 2 * 0.8f;//X軸邊緣原點到原點到距離
pHeight = mHeight / 2 * 0.8f;//Y軸邊緣原點到原點到距離
}