Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 完整的Android表情功能處理方案

完整的Android表情功能處理方案

編輯:關於Android編程

Android表情功能處理方案概述

1.原理和實現思路

2.表情圖片顯示

3.表情面板

4.表情的輸入框插入和刪除

5.表情添加腳本

Android中表情功能,一般都不是用ImageView去設置圖片實現的,表情一般會嵌套在文本之中,那麼如何實現呢,這裡就介紹一下其中的原理,此外還有相關功能的實現思路和具體代碼。

先看下良心動態圖

1.原理和思路

a.表情內容的數據格式
表情看上去是圖片,但是在數據傳輸的時候本質上是一個特殊文本;
比如QQ表情就是一個 "/表情字母"的結構,比如害羞的表情就是/hx,呲牙就是/cy...;
微博裡表情就是"[表情名字]"的接口,比如可愛的表情就是[可愛]等等...。

b.特殊文本顯示圖片的原理
需要用到安卓中的SpannableString拓展性字符串相關知識;
SpannableString可以讓一段字符串在顯示的時候,將其中某小段文字附著上其他內容;
附著的拓展內容可能是圖片,或者是文字格式,比如加粗斜體等。

下面稍微展開介紹下SpannableString,會的可以跳過

常用的拓展內容包含有
BackgroundColorSpan 背景色
ClickableSpan 文本可點擊,有點擊事件
UnderlineSpan 下劃線
ImageSpan 圖片
StyleSpan 字體樣式:粗體、斜體等
URLSpan 文本超鏈接
此外還有刪除線,縮放大小等不同樣式的拓展

用法

SpannableString spannableString = new SpannableString(source);
ImageSpan span = new ImageSpan(context, bitmap);
spannableString.setSpan(span, start, start + emojiStr.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );

解釋下用法

首先將原String文字包裝成拓展性文字SpannableString,再創建一個需要類型的Span對象,比如表情圖片就是ImageSpan,然後利用SpannableString的setSpan方法,將span對象設置在對應位置。
start就是需要附著的內容的開始位置
end是需要附著的內容的開始位置
flag標志位,這裡是最常用的EXCLUSIVE_EXCLUSIVE的表示span拓展文本不包含前後,

此外還有INCLUSIVE是包含的意思

舉例說明下,原文字是"文章作者是大帥比",那我創建個粗體拓展內容,並且要將其附著到作者二字上讓其變成粗體,那開始位置就是2,即第三個字;結束位置就是4,即第五個,然後按照"包頭不包尾"原則,包含第三個字不包含第五個字,即處理的就是第三四倆字"作者",flag我們將其設為EXCLUSIVE_INCLUSIVE即不包含前包含後。

那最終顯示的文字就是"文章作者是大帥比"
如果我們在附著內容及作者二字前面輸入內容時,由於是EXCLUSIVE不包含,所以不會跟著變化
"文章boredream作者是大帥比"
如果我們在附著內容及作者二字後面輸入內容時,由於是INCLUSIVE包含,新內容也會包含進效果
"文章作者boredream是大帥比"

c.特殊文字的匹配
知道要處理哪些特殊文本,怎麼處理,還有一步是怎麼把特殊文本從一段文字裡挑出來,即獲取到特殊本文的開始和結束位置,以及他的文字內容,這裡就要用到正則去進行匹配獲取了正則的規則就不細說了,介紹下表情這裡的正則匹配。

2.表情圖片顯示

文字附著表情圖片很簡單,用SpannableString中的ImageSpan,難點在於正則部分的獲取處理:

首先是正則的寫法,根據需要自行編寫規則,這裡以微博表情為例String regex = "\\[[\u4e00-\u9fa5\\w]+\\]";

簡單介紹下,最外面是方括號符號,要注意由於[]在正則中有特殊意義,所以需要用斜槓\轉義一下(\本身也需要轉義所以是倆\\),中間\u4e00-\u9fa5表示中文,\\w表示下劃線的任意單詞字符,+ 代表一個或者多個,那麼這段正則就代表,匹配方括號內有一或多個文字和單詞字符的文本。

然後去while循環匹配就可以了,用matcher.find獲取到匹配的開始位置,作為setSpan的start值,用matcher.group方法獲取到匹配規則的具體表情文字,end值則直接利用開始位置加上表情文字的長度即可。

貼上代碼

public static SpannableString getEmotionContent( final Context context, final TextView tv, String source) {
 SpannableString spannableString = new SpannableString(source);
 Resources res = context.getResources();

 String regexEmotion = "\\[([\u4e00-\u9fa5\\w])+\\]" ;
 Pattern patternEmotion = Pattern. compile(regexEmotion);
 Matcher matcherEmotion = patternEmotion.matcher(spannableString);

 while (matcherEmotion.find()) {
  // 獲取匹配到的具體字符
  String key = matcherEmotion.group();
  // 匹配字符串的開始位置
  int start = matcherEmotion.start();
  // 利用表情名字獲取到對應的圖片
  Integer imgRes = EmotionUtils. getImgByName(key);
  if (imgRes != null) {
   // 壓縮表情圖片
   int size = ( int) tv.getTextSize();
  Bitmap bitmap = BitmapFactory.decodeResource(res, imgRes);
  Bitmap scaleBitmap = Bitmap.createScaledBitmap(bitmap, size, size, true);

  ImageSpan span = new ImageSpan(context, scaleBitmap);
  spannableString.setSpan(span, start, start + key.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
  }
 }
 return spannableString;
}

基本思路前面提過了,圖片處理的地方還要再說明下

表情如果直接獲取資源文件裡的圖片,可能會過大,所以方法參數裡傳入了需要顯示的文字控件,然後利用文字大小去將表情圖片再壓縮一下,其中,EmotionUtils類就不介紹了,裡面就是一個map集合,key為表情名字,value為表情圖片的resId,然後提供一個getImgByName的方法可以根據名字獲取圖片鍵值對需要一個個添加比較麻煩,我們會在最後介紹一個表情添加的腳本,方便快速導入圖片資源。

3.表情面板

結構就是ViewPager提供多頁滑動,每頁都是一個GridView顯示20個表情,末尾還有一個刪除按鈕;
ViewPager和GridView的基本使用方法就不介紹了,這裡說明下其中的特殊處理;

a.每個GridView的大小設置
GridView會顯示3行7列,共21個Item,為了讓Item能大小合適,最好的方法是利用動態計算的方式設置寬高,因為屏幕寬度各有不同,其他的一些大小計算也要注意用dp值轉換下獲取對應的px再使用,保證適配問題。

思路是獲取屏幕寬度,減去間隙距離,然後除以7算出每個Item需要的寬度,然後再乘以3加上需要的間隙,算出表情面板的高度,利用算出來的值去創建設置面板大小。

b.需要多少個GridView
一共有多少頁呢,雖然表情大部分情況下總數是固定的,但是最好還是根據代碼的方式算出來需要多少頁,而非直接人去目測計算要多少個GridView。

思路是for循環全部的圖片名字,這裡利用map.keySet獲取全部的鍵集合,每次循環都把圖片名添加到一個集合中,然後進行判斷,如果滿20個了就作為一組表情,新建一個GridView設置上去,最後把所有表情生成的一個個GridView放到一個總view集合中,利用ViewPager顯示。

c.GridView末尾刪除鍵處理
適配器和點擊事件中,都利用position判斷,如果是最後一個就進行特殊的顯示和點擊處理。

這幾部分的代碼比較亂,但是沒有什麼新知識點,都是一些邏輯方面的內容,就不貼出來了。

4.表情的輸入框插入和刪除

實質上還是對表情對應的文本數據進行操作,這裡最要注意的地方是輸入框中的光標問題,輸入框其實也是TextView的一種,顯示和之前介紹的方法一樣,但是動態的添加和刪除就需要注意處理位置的問題了。

a.手動設置光標
新添加一個表情,應該是在輸入框中當前光標的位置插入圖片,所以首先要知道光標的位置獲取這裡可以用et.setSelectionStart方法;
還有一點,添加完表情以後,光標應該更新到新添加內容後面,而設置光標位置就要用et.setSelection(position)方法。

b.調用系統按鈕事件自動處理
刪除就比較簡單了,這裡直接調用系統的 Delete 按鈕事件即可,讓某個控件調用按鈕事件的方法為et.displatchKeyEvent(new KeyEvent(action, code));其中action就是動作,用ACTION_DOWN按下動作就可以了,而code為按鈕事件碼,刪除對應的就是KEYCODE_DEL。

5.表情添加腳本

以上,知識點就全部介紹完畢了,最後是福利時間。

表情少則幾十,多則甚至上百~ 一個一個的根據名字設置對應表情鍵值對會各種痛苦,這裡推薦編寫腳本進行處理,也就是寫段功能自動的生成所需代碼;

這段就比較靈活了,需要根據不同需要編寫腳本,所以主要是提供個思路然後以微博為例編寫代碼;

微博中表情是"[表情文字]",而表情圖片名字則是"d_表情拼音"(此外還有其他的名字樣式,比如h_或者emoji_等等,暫時不管,處理原理都差不多);

這裡要先說明一下前提,必須要按照一定規則來才能進行這種半自動化的處理,如果表情干脆名字就是瞎起的,那就沒轍了,如果是公司自己做應用的話,一定要讓美工切圖後導出的圖片文件名按照套路出牌;

新浪微博中d_表情拼音這裡就都是中文對應的拼音而非英文,且中文都是和[表情文字]一致的,比如害羞表情的文字就是[害羞],而圖片名字就是d_haixiu。

那微博這裡處理就可以按照套路來了
1) 打開微博原版客戶端,把所有表情全部選中,然後發出來
2) 在日志裡獲取到這段圖片對應的文字數據
3) 用表情文字規則對這段文字進行循環匹配
4) 每次循環的時候都,把匹配的表情名字轉為拼音(pinyin4j等工具)
5) 把表情文字轉成的拼音再拼成圖片資源的名字(微博這裡就是加個"d_"前綴)
6) 拼接map.put的代碼
7) 循環完成後,打印出來全部的map.put代碼,然後復制到我們的表情工具類中使用

貼上代碼,腳本直接新建一個java的項目放在main函數裡運行就可以了

public static void weiboEmoji() {
 StringBuilder sb = new StringBuilder();

 String names = "[羞羞哒甜馨][萌神奧莉][帶著微博去旅行][愛紅包][拍照][馬到成功]→_→[呵呵][嘻嘻][哈哈][愛你][挖鼻屎][吃驚][暈][淚][饞嘴][抓狂][哼][可愛][怒][汗][害羞][睡覺][錢][偷笑][笑cry][doge][喵喵][酷][衰][閉嘴][鄙視][花心][鼓掌][悲傷][思考][生病][親親][怒罵][太開心]" +
   "[懶得理你][右哼哼][左哼哼][噓][委屈][吐][可憐][打哈氣][擠眼][失望][頂][疑問][困][感冒][拜拜][黑線][陰險][打臉][傻眼][互粉][心][傷心][豬頭][熊貓][兔子]" ;

 String regexEmoji = "\\[([\u4e00-\u9fa5a-zA-Z0-9])+\\]" ;
 Pattern patternEmoji = Pattern. compile(regexEmoji);
 Matcher matcherEmoji = patternEmoji.matcher(names);

 CharacterParser parser = CharacterParser. getInstance();
 while (matcherEmoji.find()) { // 如果可以匹配到
  String key = matcherEmoji.group(); // 獲取匹配到的具體字符

  String pinyinName = "d_" + parser.getSpelling(key).replace("[" , "" ).replace("]" , "" );
  sb.append( "emojiMap.put(\"" + key + "\", R.drawable." + pinyinName + ");\n" );
 }
 System. out.println(sb.toString());
}

運行結果,從控制台復制代碼粘貼到項目裡的工具類中即可

可能有的表情文件名就是不按套路來,比如新浪微博這裡的笑哭的表情,文字就是[笑cry],而圖片文件名是d_xiaoku,那麼也沒關系,你復制到項目中,如果圖片資源匹配不上的話也會報錯提示,進行對應修改即可。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved