Android仿QQ個(gè)性標(biāo)簽功能
QQ效果:

最終效果:

分析
字體的矩形面積越來越小
字體大小越來越小
2.1 問題分解
假設(shè)我們只有一個(gè)標(biāo)簽文字,可以選擇自定義View(當(dāng)然可以選擇自定義ViewGroup),然后隨機(jī)標(biāo)簽文字的left和top,文字大小從30sp開始,然后在onDraw里面繪制矩形,在矩形里面繪制文字。
繪制第一個(gè)標(biāo)簽文字之后,我們想繪制第二個(gè)標(biāo)簽文字,如果我們還在當(dāng)前的View里面去隨機(jī)一個(gè)Rect,可能會(huì)和第一個(gè)標(biāo)簽重合,那怎么辦?我們想到了裁剪,看下圖:

2.2 如果Rect寬大于高


2.3 如果Rect高大于寬

第一個(gè)標(biāo)簽繪制完成之后,繼續(xù)在標(biāo)簽的右邊重復(fù)繪制第一個(gè)標(biāo)簽大小的標(biāo)簽,一直到Rect右邊剩余的空間不足以繪制一個(gè)當(dāng)前的大小的標(biāo)簽,然后將剩下的空間切成Rect①和Rect②,重復(fù)以上步驟。
核心代碼
3.1 定義Tag對(duì)象
public class Tag {private String name;private int left;private int top;private int right;private int bottom;private int textsize;// 省略構(gòu)造函數(shù)和setter getter}
這個(gè)class的作用類似記錄器,記錄每一個(gè)Tag的位置和文字大小信息。
3.2 核心函數(shù)
public void computeSingleRect(List<String> tags, int textSize, int pLeft, int pTop, int pRight, int pBottom) {if (tags == null || tags.size() == 0 || textSize < MIN_TEXT_SIZE || pBottom == 0 || pRight == 0 || pLeft >= pRight || pTop >= pBottom) {return;}int cLeft = 0;int cTop = 0;int cRight = 0;int cBottom = 0;int textWidth = 0;int textHeight = 0;int size = tags.size();int index = (int) (Math.random() * (size - 1));String name = tags.get(index);//計(jì)算當(dāng)前rect的寬高int rectWidth = pRight - pLeft;int rectHeight = pBottom - pTop;if (rectWidth > rectHeight) {//父布局長(zhǎng)大于高,橫向布局合適paint.setTextSize(textSize);textWidth = (int) paint.measureText(name);textHeight = (int) (paint.getFontMetrics().bottom - paint.getFontMetrics().top);if (textHeight > rectHeight) {//記錄之前的textsizeint beforeTextSize = textSize;while (textHeight > rectHeight) {textSize--;paint.setTextSize(textSize);textHeight = (int) (paint.getFontMetrics().bottom - paint.getFontMetrics().top);}textWidth = (int) paint.measureText(name);while (textWidth > rectWidth) {textSize--;paint.setTextSize(textSize);textWidth = (int) paint.measureText(name);}if(textSize < MIN_TEXT_SIZE){return;}textHeight = (int) (paint.getFontMetrics().bottom - paint.getFontMetrics().top);cLeft = pLeft;cTop = pTop;cRight = textWidth + pLeft;cBottom = textHeight + pTop;showTags.add(new Tag(name, textSize, cLeft, cTop, cRight, cBottom));textWidth = (int) paint.measureText(name);if (pRight - cRight > textWidth) {//右computeSingleRect(tags, beforeTextSize, cRight, pTop, pRight, pBottom);} else {//右computeSingleRect(tags, --textSize, cRight, pTop, pRight, pBottom);}} else {if (textWidth >= rectWidth) {while (textWidth > rectWidth) {textSize--;paint.setTextSize(textSize);textWidth = (int) paint.measureText(name);}if(textSize < MIN_TEXT_SIZE){return;}textHeight = (int) (paint.getFontMetrics().bottom - paint.getFontMetrics().top);cLeft = pLeft;cTop = pTop;cRight = pRight;cBottom = cTop + textHeight;showTags.add(new Tag(name, textSize, cLeft, cTop, cRight, cBottom));//下textSize += 4;computeSingleRect(tags, textSize, cLeft, cBottom, cRight, pBottom);} else {cLeft = (int) (Math.random() * (rectWidth / 3)) + pLeft; // 除以3是為了盡快找到合適的位置while (cLeft + textWidth > pRight) {cLeft--;}cTop = (int) (Math.random() * (rectHeight / 2)) + pTop;while (cTop + textHeight > pBottom) {cTop--;}cRight = cLeft + textWidth;cBottom = cTop + textHeight;showTags.add(new Tag(name, textSize, cLeft, cTop, cRight, cBottom));//左computeSingleRect(tags, --textSize, pLeft, pTop, cLeft, cBottom);//上computeSingleRect(tags, --textSize, cLeft, pTop, pRight, cTop);//右computeSingleRect(tags, --textSize, cRight, cTop, pRight, pBottom);//下computeSingleRect(tags, --textSize, pLeft, cBottom, cRight, pBottom);}}} else {//父布局高大于長(zhǎng),縱向布局合適int beforeTextSize = textSize;paint.setTextSize(textSize);textHeight = (int) (paint.getFontMetrics().bottom - paint.getFontMetrics().top);while (textHeight * name.length() > rectHeight) {textSize--;paint.setTextSize(textSize);textHeight = (int) (paint.getFontMetrics().bottom - paint.getFontMetrics().top);}if(textSize < MIN_TEXT_SIZE){return;}textWidth = (int) (paint.measureText(name) / name.length());int length = name.length();if (pLeft + textWidth > pRight) {//右 右邊空間不足computeSingleRect(tags, --textSize, pLeft, pTop, pRight, pBottom);return;}for (int i = 0; i < length; i++) {cLeft = pLeft;cTop = pTop + i * textHeight;cRight = cLeft + textWidth;cBottom = cTop + textHeight;showTags.add(new Tag(String.valueOf(name.charAt(i)), textSize, cLeft, cTop, cRight, cBottom));}if (pRight - cRight > textWidth) {//右computeSingleRect(tags, beforeTextSize, cRight, pTop, pRight, cBottom);//下computeSingleRect(tags, --textSize, pLeft, cBottom, pRight, pBottom);} else {//右computeSingleRect(tags, --textSize, cRight, pTop, pRight, cBottom);//下computeSingleRect(tags, --textSize, pLeft, cBottom, pRight, pBottom);}}}
Github地址:
評(píng)論
圖片
表情
