欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2016年11月21日 14:14:03   作者:boredream  
這篇文章主要為大家詳細(xì)介紹了完整的Android表情功能處理方案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

Android表情功能處理方案概述

1.原理和實(shí)現(xiàn)思路

2.表情圖片顯示

3.表情面板

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

5.表情添加腳本

Android中表情功能,一般都不是用ImageView去設(shè)置圖片實(shí)現(xiàn)的,表情一般會(huì)嵌套在文本之中,那么如何實(shí)現(xiàn)呢,這里就介紹一下其中的原理,此外還有相關(guān)功能的實(shí)現(xiàn)思路和具體代碼。

先看下良心動(dòng)態(tài)圖

1.原理和思路

a.表情內(nèi)容的數(shù)據(jù)格式
表情看上去是圖片,但是在數(shù)據(jù)傳輸?shù)臅r(shí)候本質(zhì)上是一個(gè)特殊文本;
比如QQ表情就是一個(gè) "/表情字母"的結(jié)構(gòu),比如害羞的表情就是/hx,呲牙就是/cy...;
微博里表情就是"[表情名字]"的接口,比如可愛的表情就是[可愛]等等...。

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

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

常用的拓展內(nèi)容包含有
BackgroundColorSpan 背景色
ClickableSpan 文本可點(diǎn)擊,有點(diǎn)擊事件
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,再創(chuàng)建一個(gè)需要類型的Span對(duì)象,比如表情圖片就是ImageSpan,然后利用SpannableString的setSpan方法,將span對(duì)象設(shè)置在對(duì)應(yīng)位置。
start就是需要附著的內(nèi)容的開始位置
end是需要附著的內(nèi)容的開始位置
flag標(biāo)志位,這里是最常用的EXCLUSIVE_EXCLUSIVE的表示span拓展文本不包含前后,

此外還有INCLUSIVE是包含的意思

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

那最終顯示的文字就是"文章作者是大帥比"
如果我們?cè)诟街鴥?nèi)容及作者二字前面輸入內(nèi)容時(shí),由于是EXCLUSIVE不包含,所以不會(huì)跟著變化
"文章boredream作者是大帥比"
如果我們?cè)诟街鴥?nèi)容及作者二字后面輸入內(nèi)容時(shí),由于是INCLUSIVE包含,新內(nèi)容也會(huì)包含進(jìn)效果
"文章作者boredream是大帥比"

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

2.表情圖片顯示

文字附著表情圖片很簡(jiǎn)單,用SpannableString中的ImageSpan,難點(diǎn)在于正則部分的獲取處理:

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

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

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

貼上代碼

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();
  // 利用表情名字獲取到對(duì)應(yīng)的圖片
  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;
}

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

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

3.表情面板

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

a.每個(gè)GridView的大小設(shè)置
GridView會(huì)顯示3行7列,共21個(gè)Item,為了讓Item能大小合適,最好的方法是利用動(dòng)態(tài)計(jì)算的方式設(shè)置寬高,因?yàn)槠聊粚挾雀饔胁煌?,其他的一些大小?jì)算也要注意用dp值轉(zhuǎn)換下獲取對(duì)應(yīng)的px再使用,保證適配問題。

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

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

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

c.GridView末尾刪除鍵處理
適配器和點(diǎn)擊事件中,都利用position判斷,如果是最后一個(gè)就進(jìn)行特殊的顯示和點(diǎn)擊處理。

這幾部分的代碼比較亂,但是沒有什么新知識(shí)點(diǎn),都是一些邏輯方面的內(nèi)容,就不貼出來了。

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

實(shí)質(zhì)上還是對(duì)表情對(duì)應(yīng)的文本數(shù)據(jù)進(jìn)行操作,這里最要注意的地方是輸入框中的光標(biāo)問題,輸入框其實(shí)也是TextView的一種,顯示和之前介紹的方法一樣,但是動(dòng)態(tài)的添加和刪除就需要注意處理位置的問題了。

a.手動(dòng)設(shè)置光標(biāo)
新添加一個(gè)表情,應(yīng)該是在輸入框中當(dāng)前光標(biāo)的位置插入圖片,所以首先要知道光標(biāo)的位置獲取這里可以用et.setSelectionStart方法;
還有一點(diǎn),添加完表情以后,光標(biāo)應(yīng)該更新到新添加內(nèi)容后面,而設(shè)置光標(biāo)位置就要用et.setSelection(position)方法。

b.調(diào)用系統(tǒng)按鈕事件自動(dòng)處理
刪除就比較簡(jiǎn)單了,這里直接調(diào)用系統(tǒng)的 Delete 按鈕事件即可,讓某個(gè)控件調(diào)用按鈕事件的方法為et.displatchKeyEvent(new KeyEvent(action, code));其中action就是動(dòng)作,用ACTION_DOWN按下動(dòng)作就可以了,而code為按鈕事件碼,刪除對(duì)應(yīng)的就是KEYCODE_DEL。

5.表情添加腳本

以上,知識(shí)點(diǎn)就全部介紹完畢了,最后是福利時(shí)間。

表情少則幾十,多則甚至上百~ 一個(gè)一個(gè)的根據(jù)名字設(shè)置對(duì)應(yīng)表情鍵值對(duì)會(huì)各種痛苦,這里推薦編寫腳本進(jìn)行處理,也就是寫段功能自動(dòng)的生成所需代碼;

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

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

這里要先說明一下前提,必須要按照一定規(guī)則來才能進(jìn)行這種半自動(dòng)化的處理,如果表情干脆名字就是瞎起的,那就沒轍了,如果是公司自己做應(yīng)用的話,一定要讓美工切圖后導(dǎo)出的圖片文件名按照套路出牌;

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

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

貼上代碼,腳本直接新建一個(gè)java的項(xiàng)目放在main函數(shù)里運(yùn)行就可以了

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

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

 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());
}

運(yùn)行結(jié)果,從控制臺(tái)復(fù)制代碼粘貼到項(xiàng)目里的工具類中即可

可能有的表情文件名就是不按套路來,比如新浪微博這里的笑哭的表情,文字就是[笑cry],而圖片文件名是d_xiaoku,那么也沒關(guān)系,你復(fù)制到項(xiàng)目中,如果圖片資源匹配不上的話也會(huì)報(bào)錯(cuò)提示,進(jìn)行對(duì)應(yīng)修改即可。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論