日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java xml textview居中_android—图文垂直居中 TextView+SpannableString

發(fā)布時間:2024/7/23 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java xml textview居中_android—图文垂直居中 TextView+SpannableString 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

自我感覺做什么事情都是事倍功半,同樣性格還是丟三落四的人。記錄每一次解決問題的思路經(jīng)過,以供自我學

最終效果

前幾天讓做一個效果如上圖,于是引發(fā)了一些列的思路風暴:

(思路1)TextView+Html的形式:html在網(wǎng)頁實現(xiàn)很常見的,所以不免第一個反應(yīng)就是用html。于是讓前端哥們寫了一段html文本,但是當我用著個文本顯示的時候發(fā)現(xiàn)沒有效果,于是開始想是不是因為哥們用的CSS3.0,html5的原因(因為可能手機的TextView不支持,所以可能是這原因),然后去網(wǎng)上搜索看TextView都支持什么html標簽,最后發(fā)現(xiàn)TextView支持有限的Html標簽,其中知識一些簡單的字體,顏色,背景,還不支持CSS(更不用說CSS3.0了)

思路1總結(jié):整個過程耗費了半個下午,其中還包括1一個人情(前端哥們的幫忙) 。查詢TextView具體支持標簽在Html.from("")的方法中查找

知識點總結(jié):TextView支持的html很是有限的,關(guān)于字體的樣式還是用自個的標簽。而且最后html會被轉(zhuǎn)換span的形式

(思路2)ImageScpan+自定義drawable方式:textview+html不行,那么,只能用span。為什么使用ImageSpan原因:1,因為可以把“服務(wù)中”這個塊當成圖片。如果用ImageScpan實現(xiàn)了的話,后期可以隨便換成任何圖片。2。不使用ImageSpan的話,只能使用backgroundscpan,relativespan和字體顏色span等至少三個集合,有點多了感覺,最重要的是Imagespan是可以到行尾部換行了(解釋:如果行尾的預(yù)留的寬度不夠的話,會另起一行。所選文字對于一個圖片塊),不知道其他的行不行(解釋:字面意思backgroundspan只是改變所選文章的背景色,所針對的文字還是一個對一個。另外兩個span一樣的)。使用imagespan+圖片的形式是合理的選擇,既然這個形式的話那么imagespan+自定義的drawable是最好的思路出現(xiàn)了,這里是因為自定義drawable可以繪制任何圖片。于是要自個實現(xiàn)一個drawable和系統(tǒng)的imagespan組裝這個效果。到這里以為終于可以了,走幾步才發(fā)現(xiàn),嘿嘿...

系統(tǒng)的Imagescpan不行,不能和文字垂直居中,并且當所使用圖片高度大于文字的ascent(。好像是這個。 )時,改行的行高使用會加上一定高度。于是上網(wǎng)搜索垂直居中ImageScpan 。

思路2總結(jié):整個過程進展也算合理。最后的結(jié)果是:搜索的垂直居中imagescpan+自定義drawable。(出錯了,為什么不直接寫一個自定義自個的Imagescpan呢)工作量相對多,自定義兩個東西

知識點總結(jié):

1,系統(tǒng)的Imagescpan不行,不能和文字垂直居中,并且當所使用圖片高度大于文字的ascent(。好像是這個。 )時,改行的行高使用會加上一定高度。于是上網(wǎng)搜索垂直居中ImageScpan 。

2,牽扯到了drawable自定義 ,了解到當drawable.draw(canvas)之前 drawable.getbouds返回的區(qū)域必須是有個有空間的區(qū)域。不能是高為0,寬為0,這樣的話只會看不到

3,中間搜索到了一個大神寫的垂直居中的ImageSpan

(思路3) 自定義自個的ImageSpan:直接自定義自個的span,拋棄了思路2還用自個寫自定義drawable,顯然這個是不錯的。直接朝這個方向前進吧!!最后完成了效果

思路3總結(jié):canvas.drawline的時候水平線應(yīng)該是字體的baseline的位置。

針對這個問題最終總結(jié):

1, 是因為自個不知道textview支持多少html標簽,所以有了思路1。途中得到的戰(zhàn)果

TextView支持的html很是有限的,關(guān)于字體的樣式還是用自個的標簽。而且最后html會被轉(zhuǎn)換span的形式

2, 為什么會出現(xiàn)思路2的情況,有兩個需要自定義的類,是因為當時大腦亂糾結(jié)這個問題太長時間了。沒想過直接二合一直接自定義一個 途中得到的戰(zhàn)果

系統(tǒng)的Imagescpan不行,不能和文字垂直居中,并且當所使用圖片高度大于文字的ascent(。好像是這個。 )時,改行的行高使用會加上一定高度。于是上網(wǎng)搜索垂直居中ImageScpan 。

牽扯到了drawable自定義 ,了解到當drawable.draw(canvas)之前 drawable.getbouds返回的區(qū)域必須是有個有空間的區(qū)域。不能是高為0,寬為0,這樣的話只會看不到

中間搜索到了一個大神寫的垂直居中的ImageSpan

在xml中設(shè)置textview的行高不會體現(xiàn)的設(shè)置字體高度(原以為會體現(xiàn)到字體 dscent ),只是體現(xiàn)到行與行之間的距離上

獻上最后的兩個重要的ImageSpan

網(wǎng)上搜索的某個大神:

public class VerticalImageSpan extends ImageSpan { //根據(jù)圖片調(diào)整字體,來是適應(yīng)圖片的高度

public VerticalImageSpan(Context context,int drawableid) {

super(context,drawableid);

}

/**

* update the text line height

*/

@Override

public int getSize(Paint paint,CharSequence text, intstart, intend, Paint.FontMetricsInt fontMetricsInt) { //設(shè)置圖片塊的寬度

Drawable drawable = getDrawable();

Rect rect = drawable.getBounds(); //注意點,這個rect應(yīng)該是有效的空間 高度為0,寬度為0 drawable就繪制不出來,在這個地方是用

if(fontMetricsInt !=null) { //來調(diào)整字體高度的,因為要讓文本行適應(yīng)圖片高度

Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();

int fontHeight = fmPaint.descent- fmPaint.ascent;

int drHeight = rect.bottom- rect.top;

int centerY = fmPaint.ascent+ fontHeight /2;

fontMetricsInt.ascent= centerY - drHeight /2;

fontMetricsInt.top= fontMetricsInt.ascent;

fontMetricsInt.bottom= centerY + drHeight /2;

fontMetricsInt.descent= fontMetricsInt.bottom;

}

return rect.right;

}

/**

* see detail message in android.text.TextLine

*

*@paramcanvasthe canvas, can be null if not rendering

*@paramtextthe text to be draw

*@paramstartthe text start position

*@paramendthe text end position

*@paramxthe edge of the replacement closest to the leading margin

*@paramtopthe top of the line //文本所在改行的頂部

*@paramythe baseline //文本的基準線

*@parambottomthe bottom of the line //文本所在改行的底部 及下行的頂部,xml文件中的設(shè)置的行間距會直接影響 bottom到baseline的距離

*@parampaintthe work paint

*/

@Override

public void draw(Canvas canvas,CharSequence text, int start, int end,

float x, int top, inty, int bottom,Paint paint) {

CharSequence targetText=text.subSequence(start,end);

Log.v("文字",targetText.toString());

Drawable drawable = getDrawable();

canvas.save();

Rect rect =drawable.getBounds(); //注意點,這個rect應(yīng)該是有效的空間 高度為0,寬度為0 drawable就繪制不出來,

Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();

int fontHeight = fmPaint.descent- fmPaint.ascent;

int centerY = y + fmPaint.descent- fontHeight /2;

int transY = centerY - (rect.bottom- rect.top) /2;

canvas.translate(x,transY);

drawable.draw(canvas);

canvas.restore();

}

}

這個是我最終的圖文居中span,如下:

public class CustomSpan extends ImageSpan { //圖片適應(yīng)文本行高度

int resourceId;

int textColor;

float textRadio;

int marginH;//左右間隔

Rect rect;

Drawable drawable;

publicCustomSpan(Context context, int resourceId, int textColor, float textRadio, int marginH) {

super(context,resourceId);

this.resourceId= resourceId;

drawable= context.getResources().getDrawable(resourceId);

this.textRadio= textRadio;

this.textColor= textColor;

this.marginH= marginH;

}

@Override

public int getSize(Paint paint,CharSequence text, intstart, intend,Paint.FontMetricsInt fm) { //設(shè)置圖片塊的寬度

CharSequence targetText=text.subSequence(start,end);

Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();

int txtW = (int) Math.ceil(paint.measureText(targetText.toString()));

int fontHeight = fmPaint.descent- fmPaint.ascent;

rect=newRect(0,0,txtW,fontHeight);

return rect.right+2*marginH;

}

/**

* see detail message in android.text.TextLine

*

*@paramcanvasthe canvas, can be null if not rendering

*@paramtextthe text to be draw

*@paramstartthe text start position

*@paramendthe text end position

*@paramxthe edge of the replacement closest to the leading margin

*@paramtopthe top of the line //文本所在改行的頂部

*@paramythe baseline //文本的基準線

*@parambottomthe bottom of the line //文本所在改行的底部 及下行的頂部,xml文件中的設(shè)置的行間距

會直接影響 bottom到baseline的距離

*@parampaintthe work paint

*/

@Override

public void draw(Canvas canvas,CharSequence text, int start, int end, float x, int top, int y, int bottom,Paint paint) {

CharSequence targetText=text.subSequence(start,end);

intoldTextColor =paint.getColor();

floatoldTextSize =paint.getTextSize();

// canvas.drawLine(0,top,400,top,paint);

// canvas.drawLine(0,y,400,y,paint);

// canvas.drawLine(0,bottom,400,bottom,paint);

Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();

int oldfontascent = fmPaint.ascent;

paint.setColor(textColor);

paint.setTextSize(oldTextSize*textRadio);

fmPaint = paint.getFontMetricsInt();

int txtW = (int) Math.ceil(paint.measureText(targetText.toString()));

int fontHeight = fmPaint.descent- fmPaint.ascent;

canvas.save();

canvas.translate(marginH+x,y+oldfontascent);//移動到該塊的原點

drawable.setBounds(rect);//背景的繪制

drawable.draw(canvas);

Log.e("尺寸",rect.bottom-((rect.bottom-fontHeight))+","+(0-oldfontascent*textRadio));

canvas.translate((rect.right-txtW)/2.0f,rect.bottom/2.f+fontHeight/2-fmPaint.descent); //移動的值是相對的。移動到“塊”中字體“服務(wù)中”baseline

canvas.drawText(targetText.toString(),0,0,paint);

paint.setColor(oldTextColor);

paint.setTextSize(oldTextSize);

canvas.restore();

}

}

總結(jié)

以上是生活随笔為你收集整理的java xml textview居中_android—图文垂直居中 TextView+SpannableString的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。