兩行文本前面加圖片用 ImageSpan的實(shí)現(xiàn)

先上效果圖:

Paste_Image.png

左邊應(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ì)齊

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,111評(píng)論 25 709
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,408評(píng)論 4 61
  • 前言:這5個(gè)小故事,不僅有趣,還富有哲理,特別是最后一個(gè),看得我心頭一緊,眼眶發(fā)紅。 1. 《散步》 一女在違背父...
    正好學(xué)拼讀閱讀 495評(píng)論 0 0
  • 最新版本的paragon ntfs for mac的LOGO似乎做了一些變化,像是硬盤(pán)的圖樣,感覺(jué)生動(dòng)了不少。 這...
    想干啥就干啥閱讀 3,425評(píng)論 1 0
  • 人吃的東西,構(gòu)成了身體的每個(gè)細(xì)胞。同樣,經(jīng)歷的人和事,也構(gòu)成了每個(gè)思維的細(xì)胞。如果,每天吃健康的食物,人的身體就是...
    遠(yuǎn)黛如眉閱讀 192評(píng)論 0 0

友情鏈接更多精彩內(nèi)容