2014-05-18 17 views
2

我正在一點點聊天在我的Android應用程序,我使用表情符號(表情)慢一個顯示的EditText TextView的和與SpannableString。的Android Spannabe繪文字載荷GridView和TextView中

對於我做了一個類(代碼是下面)。另外我做了一個加載所有emojis的gridview。問題是所有作品都很慢(因爲我有500個表情符號)加載和顯示錶情符號需要很多時間。以下是我正在使用的代碼。

我要尋找一個更好的算法來替換表情符號或其他方式的字符串加載表情符號,速度更快。

public class EmoticonHandler { 

private static final Map<String, Integer> emoticons = new HashMap<String, Integer>(); 

private static void addPattern(Map<String, Integer> map, String smile, 
     int resource) { 
    map.put(smile, resource); 
} 

// Add the items to the HasMap 
static { 

    // Smileys 
    addPattern(emoticons, "#ce001#", R.drawable._ce001_); 
    addPattern(emoticons, "#ce002#", R.drawable._ce002_); 
    addPattern(emoticons, "#ce003#", R.drawable._ce003_); 
    addPattern(emoticons, "#ce004#", R.drawable._ce004_); 
    // Here comes the other 500 emojis 

} 

// Get image for each text smiles 
public static void getSmiledText(Context context, Spannable span, int size) { 

    int index; 
    for (index = 0; index < span.length(); index++) { 
     for (Entry<String, Integer> entry : emoticons.entrySet()) { 
      int length = entry.getKey().length(); 
      if (index + length > span.length()) 
       continue; 
      if (span.subSequence(index, index + length).toString() 
        .equals(entry.getKey())) { 

       span.setSpan(new EmoticonSpan(context, entry.getValue(), 
         size), index, index + length, 
         Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 

       index += length - 1; 
       break; 
      } 
     } 
    } 

}} 

下面是EmoticonSpan

public class EmoticonSpan extends DynamicDrawableSpan { 

private Context context; 
private int resourceID; 
private int size; 
private Drawable drawable; 

public EmoticonSpan(Context context, int resourceID, int size) { 
    super(); 

    this.context = context; 
    this.resourceID = resourceID; 
    this.size = size; 

} 

@Override 
public Drawable getDrawable() { 

    if (drawable == null) { 
     try { 
      drawable = context.getResources().getDrawable(resourceID); 
      drawable.setBounds(0, 0, size, size); 
     } catch (Exception e) { 
      // Swallow 
     } 
    } 
    return drawable; 
} 
} 

回答

0

我也有類似的問題。結束使用表情符號地圖。只需在不超過2048X2048(最大的Android可以處理的)的(單個)圖像上填充Emojis,並將其作爲輸入網格顯示出來。然後計算X/Y位置並找出用戶指向哪個表情符號。

只記得考慮到不同的設備尺寸(MDPI ... xxxdpi),並計算與正確的滾動位置,並調整偏移。

0

這裏是不錯的代碼對你:

public class EmojiKeyboard { 

    private static final String TAG = "EmojiKeyboard"; 
    private static final String PREF_KEY_HEIGHT_KB = "EmojiKbHeight"; 

    private Context context; 
    private int screenHeight = -1; 
    private int emojiKbHeight = -1; 
    private PopupWindow emojiKeyboardPopup; 
    private View view; 
    private SharedPreferences preferences; 

    public EmojiKeyboard(Context context, View view) { 
     if (context instanceof Activity) { 
      this.context = context; 
      this.view = view; 
      preferences = context.getSharedPreferences(context.getString(R.string.app_name), Context.MODE_PRIVATE); 

      //Restore EmojiKeyboard Height 
      emojiKbHeight = preferences.getInt(PREF_KEY_HEIGHT_KB, -1); 

      //TODO support less then 11 API, and not perfect resizing when switched the keyboard 
      view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 
       @Override 
       public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 
        /* 
        * Get root view height 
        * */ 
        screenHeight = screenHeight == -1 && bottom > oldBottom 
          ? bottom 
          : screenHeight; 

        /* 
        * Calculate soft keyboard height 
        * */ 
        int dHeight = oldBottom - bottom; 
        boolean validHeight = emojiKbHeight == -1 && dHeight > 80 && bottom != oldBottom; 

        /* 
        * Сheck twice because the keyboard may have been switched 
        * */ 
        emojiKbHeight = validHeight 
          ? dHeight : emojiKbHeight != (dHeight) && dHeight > 0 
          ? dHeight 
          : emojiKbHeight; 

        /* 
        * Store emoji keyboard height into SharedPreferences 
        * */ 
        preferences.edit().putInt(PREF_KEY_HEIGHT_KB, emojiKbHeight).commit(); 

        /* 
        * If layout returned to a standard height then dismissing keyboard (OnBackPressed) 
        * */ 
        if (screenHeight == bottom) { 
         dismissEmojiKeyboard(); 
        } 

        /* 
        * Resize emoji on the go when a user switches between keyboards 
        * */ 
        resizeEmoji(); 
       } 
      }); 
     } 
    } 


    public void showEmoji() { 
     if (emojiKeyboardPopup == null) { 
      createEmojiKeyboard(); 
     } 
     if (!isShowed()) { 
      new Handler().postDelayed(new Runnable() { 
       public void run() { 
        emojiKeyboardPopup.showAtLocation(view, Gravity.BOTTOM, 0, 0); 
        resizeEmoji(); 
       } 
      }, 10L); 

     } else { 
      dismissEmojiKeyboard(); 
     } 
    } 

    public void createEmojiKeyboard() { 
     EmojiView emojiKeyboard = new EmojiView(context, EmojiView.EMOJI_DARK_STYLE, new EmojiView.onEmojiClickListener() { 
      public void onBackspace() { 
       if (((Activity) context).getWindow().getCurrentFocus() instanceof EditText) { 
        ((Activity) context).getWindow().getCurrentFocus().dispatchKeyEvent(new KeyEvent(0, 67)); 
       } 
      } 

      public void onEmojiSelected(Emojicon emojicon) { 
       if (((Activity) context).getWindow().getCurrentFocus() instanceof EditText) { 
        EmojiView.input((EditText) ((Activity) context).getWindow().getCurrentFocus(), emojicon); 
       } 
      } 
     }); 
     emojiKeyboardPopup = new PopupWindow(emojiKeyboard); 
     emojiKeyboardPopup.setHeight(View.MeasureSpec.makeMeasureSpec(setEmojiKeyboardHeight(), View.MeasureSpec.EXACTLY)); 
     emojiKeyboardPopup.setWidth(View.MeasureSpec.makeMeasureSpec(getDisplayDimensions(context).x, View.MeasureSpec.EXACTLY)); 
     emojiKeyboardPopup.setAnimationStyle(0); 
    } 

    public void dismissEmojiKeyboard() { 
     if (isShowed()) { 
      emojiKeyboardPopup.dismiss(); 
     } 
    } 

    public boolean isShowed() { 
     return emojiKeyboardPopup != null && emojiKeyboardPopup.isShowing(); 
    } 

    /* 
    * Emoji set up size 
    * */ 
    public void resizeEmoji() { 
     if (isShowed()) { 
      WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 
      WindowManager.LayoutParams layoutParams = (WindowManager.LayoutParams) emojiKeyboardPopup.getContentView().getLayoutParams(); 
      layoutParams.height = setEmojiKeyboardHeight(); 
      wm.updateViewLayout(emojiKeyboardPopup.getContentView(), layoutParams); 
     } 
    } 

    public int setEmojiKeyboardHeight() { 
     return emojiKbHeight == -1 && emojiKbHeight != screenHeight && emojiKbHeight < 80 
       ? (getDisplayDimensions(context).y/2) 
       : emojiKbHeight; 
    } 

    public Point getDisplayDimensions(Context context) { 
     Point size = new Point(); 
     WindowManager w = ((Activity) context).getWindowManager(); 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { 
      w.getDefaultDisplay().getSize(size); 
     } else { 
      Display d = w.getDefaultDisplay(); 
      size.x = d.getWidth(); 
      size.y = d.getHeight(); 
     } 
     return size; 
    } 
}