1. 程式人生 > >android之文字前面或後面多標籤

android之文字前面或後面多標籤

之前寫過一篇圖文混排的,演算法就是通過計算文字寬及行數,在換行的時候擷取文字剩餘的部分顯示在圖片下邊,

程式碼下載:demo

今天這邊是工作共常用到的,標籤在前或在最後顯示,比如帖子前邊顯示多個標籤表示精華帖、優秀帖、解決標籤等;其實主要是重寫DynamicDrawableSpan,以及通過設定SpanableStringBuilder,來顯示的。

先上圖


程式碼如下:

主要是將普通文字替換成圖片文字之後(spannaableString)追加到文字後邊

/**
     * 新增標籤
     *
     * @param tagIconPosition   將標籤放在文字的前面或者後邊
     * @param tagDrawableIdList 本地標籤的drawableId集合
     */
    private CharSequence addTagText(final int tagIconPosition, final List<Integer> tagDrawableIdList, CharSequence emojiText) {
        if (tagDrawableIdList == null || tagDrawableIdList.size() == 0) {
            return emojiText;
        }
        setText(emojiText);
        SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder("");

        for (int i = 0; i < tagDrawableIdList.size(); i++) {
            spannableStringBuilder.append("t ");
        }

        for (int i = 0; i < tagDrawableIdList.size(); i++) {
            int resourceId = tagDrawableIdList.get(i);
            TagSpan tagSpanned = new TagSpan(context, resourceId, (int) getTextSize(), TagSpan.ALIGN_BASELINE, (int) getTextSize());
            spannableStringBuilder.setSpan(tagSpanned, i * 2, i * 2 + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        CharSequence sepText = getText();
        if (tagIconPosition == START) {//icon顯示在前面
            spannableStringBuilder.append(sepText);
        } else {
            spannableStringBuilder.insert(0, sepText);
        }
//        setText(spannableStringBuilder);//最後設定
        return spannableStringBuilder;
    }


重寫DynamicDrawableSpan類,設定tag的位置,主要是因為用原生的Span會有邊界錯位的問題,所以要重寫onDraw()

程式碼如下:也不復雜,計算方式自己根據需要調整

public Drawable getDrawable() {
        if (mDrawable == null) {
            try {
                mDrawable = mContext.getResources().getDrawable(mResourceId);
                mHeight = mSize;
                mWidth = mHeight * mDrawable.getIntrinsicWidth() / mDrawable.getIntrinsicHeight();
                mTop = (mTextSize - mHeight) / 2;
                // 設定邊界還是會導致錯位
                mDrawable.setBounds(0, mTop, mWidth, mTop + mHeight);
            } catch (Exception e) {
                // swallow
            }
        }
        return mDrawable;
    }

    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
        //super.draw(canvas, text, start, end, x, top, y, bottom, paint);
        Drawable b = getCachedDrawable();
        canvas.save();

        int transY = bottom - b.getBounds().bottom;
        if (mVerticalAlignment == ALIGN_BASELINE) {// 繪製圖片的位置
            transY = top + ((bottom - top) / 2) - ((b.getBounds().bottom - b.getBounds().top) / 2) - mTop;
        }
        // 由於圖片會錯位,所以要移動這個畫布
        canvas.translate(x, transY);
        b.draw(canvas);
        canvas.restore();
    }


現在說另一種實現方式:不過就是因為這種實現方式有錯位問題,才使用方式一的,但是有些情況不需要自定義DynamicDrawableSpan就可以插入文字的,多學點無壞處吧,一併寫下來說不定以後對自己有幫助

實現方式是通過Html.fromHtml( text,imageGetter);實現的;

程式碼如下:

1 、實現一個html轉化時需要的imageGetter,主要用於識別html 帶有<img src="">的標籤

/**
	 * 注:在非同步執行緒中:先將文字表情轉換成charsequence,然後載入icon,再者將icon放在文字表情的前或後,最後通過handler在主執行緒中設定textview 下午8:47:02 Spanned
	 */
	private Spanned convertTagToIconSpanned(CharSequence emojiText, int tagIconPosition, List<Integer> tagDrawablIds) {
		StringBuilder temp = new StringBuilder();
		for (int i : tagDrawablIds) {//先將drawId轉成html標籤,
			temp.append("<img src='" + i + "'/> ");
		}

		Spanned tagSpanned = Html.fromHtml(temp.toString(), getImageGetterInstance(), null);
		if (tagIconPosition == START) {// 本地圖片放在文字前邊
			SpannableStringBuilder span = new SpannableStringBuilder(tagSpanned);
			span.append(emojiText);
			return span;
		} else if (tagIconPosition == END) {// 本地圖片放在文字後邊
			SpannableStringBuilder span = new SpannableStringBuilder(emojiText);
			span.append(tagSpanned);
			return span;
		}
		return new SpannableStringBuilder(emojiText);
	}

2、獲取標籤的圖片
/**
	 * ImageGetter用於text圖文混排
	 * 
	 * @return
	 */
	public ImageGetter getImageGetterInstance() {
		ImageGetter imgGetter = new ImageGetter() {
			@Override
			public Drawable getDrawable(String source) {// 可用於載入本地圖片和網路圖片,source就是標籤設定的<img src=""> src的值
				int fontH = (int) (getTextSize());
				int id = Integer.parseInt(source);

				Drawable d = drawableMap.get(id);

				if (d == null) {
					d = getResources().getDrawable(id);
					drawableMap.put(id, d);
				}

				int height = fontH;
				int width = (int) ((float) d.getIntrinsicWidth() / (float) d.getIntrinsicHeight()) * fontH;
				if (width == 0) {
					width = d.getIntrinsicWidth();
				}

				d.setBounds(0, 0, width, height);

				return d;
			}
		};
		return imgGetter;
	}

3,通過html轉化成 Spanned ;用於setText(),就完成設定了

Spanned tagSpanned = Html.fromHtml(temp.toString(), getImageGetterInstance(), null);

希望對你有一點幫助

相關推薦

android文字前面後面標籤

之前寫過一篇圖文混排的,演算法就是通過計算文字寬及行數,在換行的時候擷取文字剩餘的部分顯示在圖片下邊, 程式碼下載:demo 今天這邊是工作共常用到的,標籤在前或在最後顯示,比如帖子前邊顯示多個標籤表示精華帖、優秀帖、解決標籤等;其實主要是重寫DynamicDrawabl

Android在ubuntu上過濾條關鍵字日誌

1 問題 比如我們在查問題的時候,需要過濾多個關鍵字,我平時的做法是一個終端執行下面的命令,然後幾個關鍵字就幾個終端,切換來切換去不方便看日誌 adb logcat | grep ****   2 改進辦法 今天看到同事用了grep -E,我們可以通過-E這個引數過

Hash-retrieval復現旅(1)------------------------------malti-label 標籤影象的檢索程式碼復現

本文參考論文是arxiv2015的關於多標籤檢索的論文Deep Semantic Ranking Based Hashing for Multi-Label Image Retrieval,作者 Fang Zhao   Yongzhen Huang    Li

Android文字底紋

佈局程式碼為 <?xml version="1.0" encoding="utf-8"?> <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"

實現android文字左右滾動

下面貼一下程式碼: xml <com.example.masong_yuanchengdianbo.AutoScrollTextView android:layout_width="fill_parent" android:id="

Android解決太大太圖片造成的oom

在最近做的工程中發現載入的圖片太多或圖片過大時經常出現OOM問題,找網上資料也提供了很多方法,但自己感覺有點亂,特此,今天在不同型號的三款安卓手機上做了測試,因為有效果也有結果,今天小馬就做個詳細的總結,以供朋友們共同交流學習,也供自己以後在解決OOM問題上有所提高,提前講下,片幅有點長,涉及的東西太多,大家

TensorFlow 基於Inception V3的標籤分類 retrain

一、準備訓練資料 1.下載資料集 本文采用南京大學開源的資料集(點選下載:http://lamda.nju.edu.cn/files/miml-image-data.rar) 資料集中含有2000張影象,5個類,分別為 desert, mounta

在listview的前面後面添加布局控制元件

在開發中我們可能會遇到這樣的需求 在listview最下面新增一個按鈕 但是這個按鈕不是一直顯示在螢幕上 它就像listview 最後一個view 根據使用者的移動來顯示 應該怎麼實現呢 這裡要用到一個方法 ListView listView = this.getListVi

android文字滾動導航欄

        其實,我個人很喜歡寫文章和大家分享我的經驗以及成果,但是,工作了,成果就有些東西不是那麼隨便就可以跟大家分享的了,但是每每看到很多人一直以來都還賴我部落格學習android,其實內心很感動,我已經很久很久沒有更新新的內容了。這裡,釋出一個自己寫的滾動導航欄,

Android旅:突然想玩的TextView前面標籤的方法

前言 可能很多朋友在做設計稿的時候經常會遇到這種問題: 好好的textView前面加了個標籤… 這要是單行還好,直接一個drawable了事 但是多行…我可以自定義一個ShapeDrawable,實現drawableLeft,但是有個問題,

Android——線程下載演示樣例

技術分享 style lis pad range 轉載 pre fontsize response 轉載請註明出處:http://blog.csdn.net/l1028386804/article/details/46883927 一、概述 說到A

IIS IIS 7及以上域名端口綁定同一物理目錄並設置不同默認文檔

clas host doc ebs dex 導致 color 不同 amp   今天在 IIS 7 多端口或域名綁定同一物理目錄,設置不同的默認文檔遇到問題:同一物理目錄的多個站點修改任意一個站點默認文檔都會一起更改。   原因:在同一個物理目錄下只有一個 web.conf

iOS UILable 文字添加圖片 (文字前面,中間,後面添加圖)

str nbsp tab 添加 tac nsa end agen mut 1,實例化一個UILable 2, // 創建一個富文本 NSMutableAttributedString *attri = [[NSMutableAttributedString

Android從零擼美團(三) - Android標籤tab滑動切換 - 自定義View快速實現高度定製封裝

這是【從零擼美團】系列文章第三篇 【從零擼美團】是一個高仿美團的開源專案,旨在鞏固 Android 相關知識的同時,幫助到有需要的小夥伴。 GitHub 原始碼地址:github.com/cachecats/L… Android從零擼美團(一) - 統一管理 Gradle 依賴 提取到單獨檔案中 Andr

AndroidRecyclerView佈局

做一個專案的主頁面的時候,想要它呈現出來的效果,不單一,更豐富那就要使用多佈局來展現出來,那麼就要思考一個問題。他呈現的是多個佈局,怎麼才能展現出來不同的佈局?邏輯很簡單,通過設定幾個flag,來表示這些佈局當前顯示的是哪個佈局,接下來,和程式碼結合瞭解一下: 第一部分:有幾個佈局就寫幾個fla

Android粒子篇文字的粒子化運動

零、前言 1.第一次接觸粒子是在html5的canvas,說是html的canvas,倒不如說是JavaScript的canvas,畢竟核心都在js。 2.經過長久的醞釀,感覺Java實現粒子運動好像也不是什麼難事,Android粒子篇將用Android作為視口,帶你領略粒子的炫酷。 3.關於效能方面

Shiro使用者名稱密碼手機號簡訊登入(realm認證)

在登入認證中,經常需要實現使用者名稱密碼和手機號驗證碼這兩種登入方式。 最近學了Shiro,所以在這裡記錄下。 使用者名稱密碼使用的令牌自然是UsernamePasswordToken,我們可以參考UsernamePasswordToken,自定義PhoneToken,在不同的控制

Android的UI優化merge、include、ViewStub標籤的使用

最近要對新接手的一個Android專案做效能優化,經過大量的查閱學習,總結了一些知識點,特此記錄。此篇記錄UI效能方面的優化思路。 說起UI的優化,不得不瞭解一下過度繪製的概念、產生原因和表現、檢視以及優化overdraw的方法。 1. 過度繪製(Ov

Android靜態文字和按鈕的互動

佈局程式碼 <?xml version="1.0" encoding="utf-8"?> <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"

Android執行緒

這是一個每過三秒 定時彈出一個Toast的小demo Android的執行緒分兩類 一個是不帶訊息的普通執行緒 另一個則是帶訊息的訊息執行緒 先來逐步分析 首先分析訊息處理器Handler 用一個匿名內部類 重寫handleMessage方法 傳入msg 按套路