基于Android開發(fā)支持表情的實(shí)現(xiàn)詳解
最近項(xiàng)目需要支持表情,表情的添加和解析實(shí)現(xiàn)基本上是參照Android自身的SmileyParser,具體就不多講了,直接貼上代碼:
public class SmileyParser {
private static SmileyParser sInstance = null;
private Context mContext = null;
private Pattern mPattern = null;
private HashMap<String, Integer> mSmileyTextToId = null;
private final String[] mSmileyArrays =
{"/西瓜","89","/便便","59","/太陽(yáng)","74","/偷笑","20","/傲慢","23","/再見","39","/凋謝","64","/發(fā)呆","3","/發(fā)怒","11","/閃電","54","/可愛","21","/豬頭","46","/咖啡","60","/哈欠","104","/鄙視","105","/委屈","106","/快哭了","107","/陰險(xiǎn)","108","/親親","109","/嚇","110","/可憐","111","/菜刀","112","/啤酒","113","/籃球","114","/乒乓","115","/示愛","116","/瓢蟲","117","/抱拳","118","/勾引","119","/拳頭","120","/差勁","121","/愛你","122","/NO","123","/OK","124","/轉(zhuǎn)圈","125","/磕頭","126","/回頭","127","/跳繩","128","/揮手","129","/激動(dòng)","130","/街舞","131","/獻(xiàn)吻","132","/左太極","133","/右太極","134","/吐","19","/蛋糕","53","/呲牙","13","/咒罵","31","/足球","57","/噓","33","/困","25","/大兵","29","/大哭","9","/強(qiáng)","76","/奮鬥","30","/擁抱","49","/害羞","6","/尷尬","10","/右哼哼","103","/慪火","86","/勝利","79","/得意","4","/驚訝","14","/心碎","67","/驚恐","26","/微笑","0","/憨笑","28","/抓狂","18","/折磨","35","/發(fā)抖","41","/握手","78","/飛吻","85","/鼓掌","99","/撇嘴","1","/敲打","38","/暈","34","/月亮","75","/流汗","27","/流淚","5","/糗大了","100","/愛心","66","/左哼哼","102","/玫瑰","63","/疑問","32","/白眼","22","/睡","8","/冷汗","96","/示愛","65","/弱","77","/跳跳","43","/色","2","/炸彈","55","/壞笑","101","/衰","36","/刀","56","/調(diào)皮","12","/摳鼻","98","/酷","16","/禮物","69","/閉嘴","7","/難過","15","/饑餓","24","/飯","61","/骷髏","37","/愛情","42"};
private int[] mSmileyIds = null;
private String[] mSmileyTexts = null;
public static SmileyParser getInstance() {
if (sInstance == null) {
sInstance = new SmileyParser(GameDataMgr.getInstance().getActivity());
}
return sInstance;
}
private SmileyParser(Context context) {
// TODO Auto-generated constructor stub
mContext = context;
initSmileyIds();
mPattern = buildPattern();
mSmileyTextToId = buildSmileyRes();
}
private void initSmileyIds(){
mSmileyIds = new int[mSmileyArrays.length / 2];
mSmileyTexts = new String[mSmileyArrays.length /2];
for (int i = 0; i < mSmileyArrays.length / 2; i++) {
mSmileyTexts[i] = mSmileyArrays[i*2];
mSmileyIds[i] = Integer.parseInt(mSmileyArrays[i*2 + 1]);
}
}
public int[] getSmileyIDs(){
return mSmileyIds;
}
public int getSmileyResourceId(int smileyId){
String idString = "face_" + Integer.toString(smileyId);
int id = getResId(idString, mContext, R.drawable.class);
return id;
}
public static int getResId(String variableName, Context context, Class<?> c) {
try {
Field idField = c.getDeclaredField(variableName);
return idField.getInt(idField);
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
public String[] getSmileyTexts(){
return mSmileyTexts;
}
Drawable getSmileyDrawable(int id){
Drawable drawable = null;
drawable = mContext.getResources().getDrawable(getSmileyResourceId(id));
return drawable;
}
/**
* 建立String - Id的對(duì)應(yīng)關(guān)系
*/
private HashMap<String, Integer> buildSmileyRes(){
HashMap<String, Integer> smileyTextToId = new HashMap<String, Integer>(mSmileyIds.length);
for(int i = 0;i < mSmileyIds.length;++i){
smileyTextToId.put(mSmileyTexts[i], mSmileyIds[i]);
}
return smileyTextToId;
}
/**
* 建立匹配用的正則表達(dá)式
* @return
*/
private Pattern buildPattern(){
StringBuilder builder = new StringBuilder(mSmileyTexts.length * 3);
builder.append('(');
for (String s: mSmileyTexts) {
builder.append(Pattern.quote(s));
builder.append('|');
}
builder.replace(builder.length() - 1, builder.length(), ")");
return Pattern.compile(builder.toString());
}
/**
* 把文字轉(zhuǎn)換為圖片
* @param text
* @return
*/
public Spannable addSmileySpans(CharSequence text){
SpannableStringBuilder spBuilder = new SpannableStringBuilder(text);
Matcher matcher = mPattern.matcher(text);
while (matcher.find()) {
int id = mSmileyTextToId.get(matcher.group());
matcher.start(),matcher.end(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spBuilder.setSpan(new ImageSpan(mContext,getSmileyResourceId(id),ImageSpan.ALIGN_BASELINE), matcher.start(),matcher.end(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return spBuilder;
}
}
實(shí)現(xiàn)過程中遇到個(gè)小問題:往TextView中添加表情時(shí),當(dāng)文本既有表情也有文字時(shí),顯示是正常的,但是當(dāng)文本中只有表情時(shí),發(fā)現(xiàn)表情顯示會(huì)偏上,而且上面有一部分被截?cái)唷?br>
TextView布局如下:
<TextView
android:id="@+id/comment_item_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:textSize="16sp"
android:textColor="#333333"
/>
解決方法:這里的問題應(yīng)該是TextView在判斷行距的時(shí)候是根據(jù)字體來(lái)判斷的,但是當(dāng)文本是表情的時(shí)候這個(gè)判斷有些問題,導(dǎo)致行距過小,所以顯示表情的時(shí)候就截?cái)嗔?,解決方法是設(shè)置一下TextView的最小高度,同時(shí)要指定文本向下對(duì)齊。另外在創(chuàng)建ImagePan的時(shí)候如果指定ImageSpan.ALIGN_BOTTOM對(duì)齊方式一般是不會(huì)出現(xiàn)這個(gè)問題的,但是這種方式下表情顯示會(huì)偏下。
修改后TextView布局如下:
<TextView
android:id="@+id/comment_item_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:textSize="16sp"
android:textColor="#333333"
android:minHeight="25dp"
android:gravity="bottom"
/>
- Android開發(fā)技巧之像QQ一樣輸入文字和表情圖像
- Android自帶emoji表情的使用方法詳解
- Android編程實(shí)現(xiàn)QQ表情的發(fā)送和接收完整實(shí)例(附源碼)
- 完整的Android表情功能處理方案
- Android編程開發(fā)實(shí)現(xiàn)TextView顯示表情圖像和文字的方法
- 詳解Android過濾emoji表情正則表達(dá)式
- android高仿微信表情輸入與鍵盤輸入代碼(詳細(xì)實(shí)現(xiàn)分析)
- Android EdText編輯框禁止輸入表情符號(hào)(使用正則表達(dá)式)
- Android輸入框添加emoje表情圖標(biāo)的實(shí)現(xiàn)代碼
- Android實(shí)現(xiàn)表情功能
相關(guān)文章
使用android-apktool來(lái)逆向(反編譯)APK包方法介紹
這篇文章主要介紹了使用android-apktool來(lái)逆向(反編譯)APK包方法介紹,本文講解了版本問題、使用apktool、反編譯decode、rebuild重打包等內(nèi)容,需要的朋友可以參考下2015-04-04Android 中ScrollView嵌套GridView,ListView的實(shí)例
這篇文章主要介紹了Android 中ScrollView嵌套GridView,ListView的實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03Android自定義控件實(shí)現(xiàn)滑動(dòng)開關(guān)效果
這篇文章主要為大家詳細(xì)介紹了Android自定義控件實(shí)現(xiàn)滑動(dòng)開關(guān)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-07-07Android 出現(xiàn)問題Installation error: INSTALL_FAILED_CONFLICTING_P
這篇文章主要介紹了Android 出現(xiàn)問題Installation error: INSTALL_FAILED_CONFLICTING_PROVIDER解決辦法的相關(guān)資料,需要的朋友可以參考下2016-12-12Kotlin語(yǔ)言中CompileSdkVersion與targetSdkVersion的區(qū)別淺析
這篇文章主要介紹了Kotlin語(yǔ)言中CompileSdkVersion和targetSdkVersion有什么區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-02-02Android簡(jiǎn)易電話撥號(hào)器實(shí)例詳解
這篇文章主要為大家詳細(xì)介紹了Android簡(jiǎn)易電話撥號(hào)器實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07RecyclerView滑動(dòng)到指定Position的方法
這篇文章主要為大家詳細(xì)介紹了RecyclerView滑動(dòng)到指定Position的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04