1. 程式人生 > >android 實現類似qq表情

android 實現類似qq表情

在自己做一個聊天應用練習的時候,需要用到表情,於是就想著模仿一下QQ表情,圖片資源完全copy的QQ.apk,解壓就可以得到,這裡不細說。

下面將該應用中的表情模組功能抽離出來,以便自己以後複習回顧。。

先看一下效果圖:

首先進入介面:(完全仿照QQ)

點選一下上面的表情圖示:

選擇一些表情,輸入一些文字混合:

點擊發送:

可以看到文字和表情圖片都一起顯示出來了。

下面列出一些關鍵程式碼:

表情工具類ExpressionUtil:

  1. publicclass ExpressionUtil {  
  2.     /** 
  3.      * 對spanableString進行正則判斷,如果符合要求,則以表情圖片代替
     
  4.      * @param context 
  5.      * @param spannableString 
  6.      * @param patten 
  7.      * @param start 
  8.      * @throws SecurityException 
  9.      * @throws NoSuchFieldException 
  10.      * @throws NumberFormatException 
  11.      * @throws IllegalArgumentException 
  12.      * @throws IllegalAccessException 
  13.      */
  14.     public
    staticvoid dealExpression(Context context,SpannableString spannableString, Pattern patten, int start) throws SecurityException, NoSuchFieldException, NumberFormatException, IllegalArgumentException, IllegalAccessException {  
  15.         Matcher matcher = patten.matcher(spannableString);  
  16.         while
     (matcher.find()) {  
  17.             String key = matcher.group();  
  18.             if (matcher.start() < start) {  
  19.                 continue;  
  20.             }  
  21.             Field field = R.drawable.class.getDeclaredField(key);  
  22.             int resId = Integer.parseInt(field.get(null).toString());       //通過上面匹配得到的字串來生成圖片資源id
  23.             if (resId != 0) {  
  24.                 Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resId);      
  25.                 ImageSpan imageSpan = new ImageSpan(bitmap);                //通過圖片資源id來得到bitmap,用一個ImageSpan來包裝
  26.                 int end = matcher.start() + key.length();                   //計算該圖片名字的長度,也就是要替換的字串的長度
  27.                 spannableString.setSpan(imageSpan, matcher.start(), end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);   //將該圖片替換字串中規定的位置中
  28.                 if (end < spannableString.length()) {                        //如果整個字串還未驗證完,則繼續。。
  29.                     dealExpression(context,spannableString,  patten, end);  
  30.                 }  
  31.                 break;  
  32.             }  
  33.         }  
  34.     }  
  35.     /** 
  36.      * 得到一個SpanableString物件,通過傳入的字串,並進行正則判斷 
  37.      * @param context 
  38.      * @param str 
  39.      * @return 
  40.      */
  41.     publicstatic SpannableString getExpressionString(Context context,String str,String zhengze){  
  42.         SpannableString spannableString = new SpannableString(str);  
  43.         Pattern sinaPatten = Pattern.compile(zhengze, Pattern.CASE_INSENSITIVE);        //通過傳入的正則表示式來生成一個pattern
  44.         try {  
  45.             dealExpression(context,spannableString, sinaPatten, 0);  
  46.         } catch (Exception e) {  
  47.             Log.e("dealExpression", e.getMessage());  
  48.         }  
  49.         return spannableString;  
  50.     }  
  51. }  


在顯示聊天頁面的list的介面卡中,我們需要做如下的顯示,即呼叫上面工具類的方法:

SimpleChatAdapter中的內部類ViewHolder:

  1. privateclass ViewHolder{  
  2.         RelativeLayout chat_layout;  
  3.         ImageView image;  
  4.         TextView text;  
  5.         public ViewHolder(View convertView){  
  6.             chat_layout=(RelativeLayout) convertView.findViewById(R.id.team_singlechat_id_listiteam);  
  7.             image=(ImageView) convertView.findViewById(R.id.team_singlechat_id_listiteam_headicon);  
  8.             text=(TextView) convertView.findViewById(R.id.team_singlechat_id_listiteam_message);  
  9.         }  
  10.         publicvoid setData(MessageInfo msg){  
  11.             RelativeLayout.LayoutParams rl_chat_left=((RelativeLayout.LayoutParams)chat_layout.getLayoutParams());  
  12.             RelativeLayout.LayoutParams rl_tv_msg_left=((RelativeLayout.LayoutParams)text.getLayoutParams());  
  13.             RelativeLayout.LayoutParams rl_iv_headicon_left=((RelativeLayout.LayoutParams)image.getLayoutParams());  
  14.             if(!DicqConstant.DEFAULTMAC.equalsIgnoreCase(msg.getUsermac())){    //根據本地的mac地址來判斷該條資訊是屬於本人所說還是對方所說
  15.                                                                                 //如果是自己說的,則顯示在右邊;如果是對方所說,則顯示在左邊
  16.                 rl_chat_left.addRule(RelativeLayout.ALIGN_PARENT_LEFT,-1);  
  17.                 rl_chat_left.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,0);  
  18.                 rl_iv_headicon_left.addRule(RelativeLayout.ALIGN_PARENT_LEFT,-1);  
  19.                 rl_iv_headicon_left.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,0);  
  20.                 rl_tv_msg_left.addRule(RelativeLayout.RIGHT_OF,R.id.team_singlechat_id_listiteam_headicon);  
  21.                 rl_tv_msg_left.addRule(RelativeLayout.LEFT_OF,0);  
  22.                 text.setBackgroundResource(R.drawable.balloon_l_selector);  
  23.             }else{  
  24.                 rl_chat_left.addRule(RelativeLayout.ALIGN_PARENT_LEFT,0);  
  25.                 rl_chat_left.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,-1);  
  26.                 rl_iv_headicon_left.addRule(RelativeLayout.ALIGN_PARENT_LEFT,0);  
  27.                 rl_iv_headicon_left.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,-1);  
  28.                 rl_tv_msg_left.addRule(RelativeLayout.RIGHT_OF,0);  
  29.                 rl_tv_msg_left.addRule(RelativeLayout.LEFT_OF,R.id.team_singlechat_id_listiteam_headicon);  
  30.                 text.setBackgroundResource(R.drawable.balloon_r_selector);  
  31.             }  
  32.             image.setImageResource(PrortaitUtils.conversionIdToRes(msg.getProtrait()));     //設定頭像
  33.             String str = msg.getMsg();                                                      //訊息具體內容
  34.             String zhengze = "f0[0-9]{2}|f10[0-7]";                                         //正則表示式,用來判斷訊息內是否有表情
  35.             try {  
  36.                 SpannableString spannableString = ExpressionUtil.getExpressionString(context, str, zhengze);  
  37.                 text.setText(spannableString);  
  38.             } catch (NumberFormatException e) {  
  39.                 e.printStackTrace();  
  40.             } catch (SecurityException e) {  
  41.                 e.printStackTrace();  
  42.             } catch (IllegalArgumentException e) {  
  43.                 e.printStackTrace();  
  44.             }  
  45.         }  
  46.     }  


關於表情彈出框的實現如下:

MainActivity:

  1. /** 
  2.      * 建立一個表情選擇對話方塊 
  3.      */
  4.     privatevoid createExpressionDialog() {  
  5.         builder = new Dialog(MainActivity.this);  
  6.         GridView gridView = createGridView();  
  7.         builder.setContentView(gridView);  
  8.         builder.setTitle("預設表情");  
  9.         builder.show();  
  10.         gridView.setOnItemClickListener(new OnItemClickListener() {  
  11.             @Override
  12.             publicvoid onItemClick(AdapterView<?> arg0, View arg1, int arg2,  
  13.                     long arg3) {  
  14.                 Bitmap bitmap = null;  
  15.                 bitmap = BitmapFactory.decodeResource(getResources(), imageIds[arg2 % imageIds.length]);  
  16.                 ImageSpan imageSpan = new ImageSpan(MainActivity.this, bitmap);  
  17.                 String str = null;  
  18.                 if(arg2<10){  
  19.                     str = "f00"+arg2;  
  20.                 }elseif(arg2<100){  
  21.                     str = "f0"+arg2;  
  22.                 }else{  
  23.                     str = "f"+arg2;  
  24.                 }  
  25.                 SpannableString spannableString = new SpannableString(str);  
  26.                 spannableString.setSpan(imageSpan, 04, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  27.                 edit.append(spannableString);  
  28.                 builder.dismiss();  
  29.             }  
  30.         });  
  31.     }  
  32.     /** 
  33.      * 生成一個表情對話方塊中的gridview 
  34.      * @return 
  35.      */
  36.     private GridView createGridView() {  
  37.         final GridView view = new GridView(this);  
  38.         List<Map<String,Object>> listItems = new ArrayList<Map<String,Object>>();  
  39.         //生成107個表情的id,封裝
  40.         for(int i = 0; i < 107; i++){  
  41.             try {  
  42.                 if(i<10){  
  43. 相關推薦

    android 實現類似qq表情

    在自己做一個聊天應用練習的時候,需要用到表情,於是就想著模仿一下QQ表情,圖片資源完全copy的QQ.apk,解壓就可以得到,這裡不細說。 下面將該應用中的表情模組功能抽離出來,以便自己以後複習回顧。。 先看一下效果圖: 首先進入介面:(完全仿照QQ) 點選

    Android: 實現類似QQ、微信的表情輸入鍵盤

    需求 最近在寫北郵人論壇客戶端時,有一個需求是實現像手機QQ、微信那樣的表情輸入鍵盤,效果圖: 表情鍵盤本身並不難做,無非就是一個帶SlidingTab的ViewPager,困擾我的地方在於,如何正確處理系統軟鍵盤與表情鍵盤之間的顯隱關係。 Google了一下,大概有這麼幾種思路: 第一種:動態改變So

    Android實現類似QQ的滑動刪除效果

    觀察QQ的滑動刪除效果,可以猜測可以滑動刪除的部分主要包含兩個部分,一個是內容區域(用於放置正常顯示的view),另一個是操作區域(用於放置刪除按鈕)。預設情況下,操作區域是不顯示的,內容區域的大小是填充整個容器,操作區域始終位於內容區域的右面。當開始滑動的時候,整個容器中

    android開發之&使用ViewPager加gridView實現選單按鈕分頁滑動(類似QQ表情選擇翻頁效果)

    剛做的專案中要用到選單分頁,以前沒做過,仔細想了想,既然是分頁,肯定就少不了ViewPager,大家都知道gridView可以實現九宮格,剛好滿足我們的需求,我做的是gridview單行顯示,大家如果需要向QQ表情一樣多行顯示,直接修改資料來源就可以。 好了,上程式碼 pu

    IM即時通訊專案講解(一)--實現類似qq微信表情面板無縫切換

    該系列技術課程來源慕課IM實戰 通過該課程可以學習到以下知識點 1、瞭解和開發後臺專案(這個是需要長期積累的,有了這個可以說入門沒問題) 2、學習到IM相關知識點,建立群、新增群、單聊、群聊 3、可以學習到資料庫的相關操作(建表、表之間的關聯等知識

    Android使用ViewPager、PhotoView實現類似QQ空間圖片瀏覽功能

    最近的專案中需要用到類似QQ空間那樣的圖片瀏覽功能,於是Google了一波,發現使用ViewPager與PhotoView即可實現。有了思路便開擼了。 首先,我們定義一個用於展示原圖的Activity。 public class ImageBrows

    android類似 QQ震動視窗的實現,帶聲音和振動效果

    效果就是如標題。好了,直接上程式碼 其實手機上看著的振動效果就是1個  animation 首先寫1個 Interpolator  -  定義一個動畫的變化率(the rate of change)這使得基本的動畫效果(alpha, scale, translate, ro

    詳解C# 網絡編程系列:實現類似QQ的即時通信程序

    並且 會話 hat chat .sh odin unicode 情況 plist 引言: 前面專題中介紹了UDP、TCP和P2P編程,並且通過一些小的示例來讓大家更好的理解它們的工作原理以及怎樣.Net類庫去實現它們的。為了讓大家更好的理解我們平常中常見的軟件QQ的工作原理

    詳解C# 網路程式設計系列:實現類似QQ的即時通訊程式

    https://www.jb51.net/article/101289.htm   引言: 前面專題中介紹了UDP、TCP和P2P程式設計,並且通過一些小的示例來讓大家更好的理解它們的工作原理以及怎樣.Net類庫去實現它們的。為了讓大家更好的理解我們平常中常見的軟體QQ的工作原理,所以在本專題

    完美實現類似QQ的自拍頭像、上傳頭像功能!(Demo 原始碼)

    現在很多下載客戶端程式都需要設定自己頭像的功能,而設定頭像一般有兩種方式:使用攝像頭自拍頭像,或者選擇一個圖片的某部分割槽域作為自己的頭像。一.相關技術  若要實現上述的自拍頭像和上傳頭像的功能,會碰到

    Android實現類似股票列表聯動

    package com.example.leftrightdemo; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.graphics.Color; import

    Android 實現類似於淘寶頭條的熱點滾動推薦

      其實原理很簡單。使用ViewFlipper,然後把要滾動的控制元件新增進去就可以了,當然首先得感謝各位前輩先寫好底層的東西~~~~ 步驟: 第一現在佈局檔案裡面定義佈局,如下所示,可根據需要自己定義ViewFlipper <ViewFlipper andr

    Java中單點登入的實現——類似QQ“頂號”操作

    簡介   對於目前的網路環境而言,在開發的系統中建立一個完善的賬號系統尤為重要。而其中的一個手段就是進行多點登入的限制。類似於騰訊qq應用軟體的機制,在其他裝置上登入自己賬號的時候,當前登入會被踢出。這樣就避免了一些自己本身的失誤或者一些惡意的賬號攻擊。

    安卓開發中使用ListView實現類似QQ聊天框(總結)

    效果如下:(現在有點醜,至於每個item的背景,可以自己處理圖片)思路:看見上圖的效果,既然是兩種不同的效果,肯定是要用資料介面卡的。MutiLayoutAdapter.java的程式碼如下:package com.deepreality.mutilayoutadapterd

    Android實現仿qq側邊欄效果

    public class MenuActivity extends FragmentActivity implements View.OnClickListener{ private ResideMenu resideMenu; private MenuActivity mContext;

    Android實現類似execel的表格 能回顯並能修改表格內容

    自定義實現一個水平滾動控制元件HorizontalScrollView package com.example.view; import android.content.Context; import android.util.Attribu

    WinForm實現類似QQ停靠,顯示隱藏過程新增特效效果

    這可能是個老題長談的問題了,只是在專案中會用到這個效果,所以今天做個記錄。大家見了別噴我。在專案中的需求是這樣的。 開啟程式,在螢幕的右下角會顯示一個窗體,一般情況下該窗體會隱藏停靠在右邊,只露出很小部分,當滑鼠移動到這個很小部分時,窗體全部顯示,顯示過程是從右邊滑動到

    Android實現類似Excel的大表格,可橫向縱向滑動,帶表頭

    在專案中遇到了這樣的需求,先是找到了這個庫: https://github.com/Kelin-Hong/ScrollablePanel 但是發現橫向滑動時很卡,縱向滑動也不那麼絲滑,後來網上翻了翻,想了想實現思路,自己動手做了個庫。 還有一篇文章是部

    android實現仿QQ登陸介面的多賬號儲存

    android應用程式中有些使用到使用者賬號登入,例如QQ登入,登入介面需要使用者輸入賬號,為了提高使用者體驗,應該儘量減少使用者的輸入操作,因此需要將使用者登入過的賬號儲存下來,以供下次使用。儲存登入賬號是一個小量資料,使用Sharedpreferences或普通檔案均可實現。以下程式程式碼儲存使用者使

    Android編寫一個登入介面,利用資料庫實現記住密碼,註冊賬號,強制下線,以及類似QQ的下拉列表登入功能

            首先呢,看到這麼長的標題,是不是感覺這些功能有點難以實現呢,哈哈,其實並沒有想象中的那麼複雜,下面就跟著筆者來一起學習一下這些功能是怎麼實現的吧!         1.建立一個所有活動的父類,繼承自A