先上效果圖:
左邊應(yīng)該是個(gè)圖片,右邊就是文本中狂,并且第二行是與圖片的左邊相對(duì)齊的凫碌。
這是一個(gè)排行榜,總共有10個(gè)條目胃榕,一開(kāi)始UI 就給切了1-3三個(gè)icon盛险,但是經(jīng)過(guò)考慮以后,這個(gè)標(biāo)題是兩行跟一行混排的這種勋又,如果是1行文本的話還好說(shuō)苦掘,但是還有2行的情況必須還要考慮,沒(méi)辦法這種情況下只能讓 UI 把1-10的 icon 圖片全部切給我們楔壤。
一開(kāi)始做的時(shí)候鹤啡,在文本前面加圖片我們一般用 TextView 的 drawableLeft 屬性,但是在實(shí)際運(yùn)行展示的話達(dá)不到我們要求的效果蹲嚣,在兩行文本的時(shí)候圖片會(huì)占據(jù)兩行递瑰,第二行的文本對(duì)其的是圖片的右邊沿。
沒(méi)辦法了只能考慮用 SpannableString 還有ImageSpan 來(lái)實(shí)現(xiàn)隙畜。
具體代碼如下:
SpannableString ss = new SpannableString(position +" "+ data.title);
//得到drawable對(duì)象抖部,即所要插入的圖片
Drawable d = context.getResources().getDrawable(ranks[position]);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
ss.setSpan(span, 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
這個(gè)地方要注意 setSpan 里面的0跟1 這兩個(gè)參數(shù),里面的參數(shù)代表的一個(gè)是 start 一個(gè)是 end 就是在字符串中所占的位置议惰,如果都設(shè)置為0慎颗,0的話就看不到圖片了,再加上圖片與文字之間還有空間言询,這樣的話就需要我們手動(dòng)在要展示的字符串加上任意字符還有加的空格俯萎,這就是上圖代碼中 position +" "+ data.title參數(shù)的由來(lái)。
這應(yīng)該是我們常用的設(shè)置运杭,但是展示的時(shí)候有些問(wèn)題夫啊,因?yàn)閳D片比較大展示的時(shí)候相比較在文字的上方,展示要求的話是在圖片與文本居中县习。
首先想到的是 setBounds 方法涮母,里面的參數(shù)是設(shè)置圖片的位置的,手動(dòng)改變初始的位置改為負(fù)值看看能不能是圖片向下展示躁愿,但是都失敗了叛本,個(gè)人感覺(jué)這個(gè)地方最低應(yīng)該就是以文本的展示的最低點(diǎn)為參考的,就是0 彤钟,0 開(kāi)始的来候。
沒(méi)辦法只能上網(wǎng)谷歌了,最終代碼如下:
SpannableString ss = new SpannableString(position +" "+ data.title);
//得到drawable對(duì)象逸雹,即所要插入的圖片
ImageSpan span = new MyIm(context, ranks[position]);
ss.setSpan(span, 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
holder.tvTitle.setText(ss);
public class MyIm extends ImageSpan
{
public MyIm(Context arg0,int arg1) {
super(arg0, arg1);
}
public int getSize(Paint paint, CharSequence text, int start, int end,
Paint.FontMetricsInt fm) {
Drawable d = getDrawable();
Rect rect = d.getBounds();
if (fm != null) {
Paint.FontMetricsInt fmPaint=paint.getFontMetricsInt();
int fontHeight = fmPaint.bottom - fmPaint.top;
int drHeight=rect.bottom-rect.top;
int top= drHeight/2 - fontHeight/4;
int bottom=drHeight/2 + fontHeight/4;
fm.ascent=-bottom;
fm.top=-bottom;
fm.bottom=top;
fm.descent=top;
}
return rect.right;
}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end,
float x, int top, int y, int bottom, Paint paint) {
Drawable b = getDrawable();
canvas.save();
int transY = 0;
transY = ((bottom-top) - b.getBounds().bottom)/2+top;
canvas.translate(x, transY);
b.draw(canvas);
canvas.restore();
}
}
這里要注意营搅,一行文本的話重寫(xiě) ImageSpan的 draw( )方法就行了云挟,但是兩行的話就不行了,還是原先的問(wèn)題转质,這樣的話就需要再重寫(xiě)getSize( )方法了园欣。
水平有限,如果寫(xiě)的有問(wèn)題的話請(qǐng)各位大大不吝賜教休蟹。
參考文章:
Android ImageSpan與TextView中的text居中對(duì)齊問(wèn)題解決
Android ImageSpan的圖文居中對(duì)齊