2016-01-31 33 views
0

我有一個軟鍵盤連接問題,並且emojione圖像由ankushsachdeva自定義執行emojicon鍵盤。Android Spannable - 表情符號刪除UTF 16

https://github.com/ankushsachdeva/emojicon

它發生,當我插入一些新的表情符號的UTF-16格式,像這樣的家庭表情:http://www.unicode.org/Public/emoji/2.0//emoji-zwj-sequences.txt

或不同膚色的笑臉。 unicode被我的ImageSpans正確替換。

當我按下表情符號鍵盤中的我的特殊後退按鈕時,通過調用keyevent刪除完整的表情符號。

mEmojiView.setOnEmojiconBackspaceClickedListener(new EmojiView.OnEmojiconBackspaceClickedListener() { 
     @Override 
     public void onEmojiconBackspaceClicked(View v) { 
      KeyEvent event = new KeyEvent(
        0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL); 
      send_text.dispatchKeyEvent(event); 
     } 
    }); 

但這裏的問題是:

當我嘗試按默認的鍵盤在鍵盤上退格按鈕,它由炭炭刪除,而不是整個的表情符號。

由於新的笑臉由多個chars/unicode代理組成,因此我必須多次按下退格按鈕並面對一些奇怪的其他笑臉組合。

當我嘗試通過長時間按下EditText來選擇表情符號時,它甚至會出現一些奇怪的行爲,它只會選擇第一個到較長表情符號的字符,但會標記整個ImageSpan。

任何建議如何解決它?

回答

0

感謝Gabe Sechan的幫助。

以下是一些適用於我的代碼。隨意添加改進。

在自定義的EditText固定的選擇:

LinkedList<EmojiData.EmojiTupel> mEmojis = new LinkedList<>(); 
boolean fromReselecting = false; 
@Override 
protected void onSelectionChanged(int selStart, int selEnd) { 
    //Log.d("Selection changed", selStart + " " + selEnd + " length: " + getText().length()); 
    if(!fromReselecting && selStart != selEnd){ 
     EmojiData.EmojiTupel toFix = inBetweenEmoji(selStart, selEnd); 
     if(toFix != null){ 
        fromReselecting = true; 
        setSelection(toFix.start, toFix.end); 
     } 
    } 
    else{ 
     fromReselecting = false; 
    } 
} 

private EmojiData.EmojiTupel inBetweenEmoji(int selStart, int selEnd){ 
    if(mEmojis == null){ 
     return null; 
    } 
    for (EmojiData.EmojiTupel tupel: mEmojis) { 
     if((tupel.start < selStart && selEnd <= tupel.end) || 
       (tupel.start <= selStart && selEnd < tupel.end) 
       ){ 
      //Log.d("InBetween ", "Selection: " + selStart + " " + selEnd + " Emoji: " + tupel.start + " "+ tupel.end); 
      return tupel; 
     } 
    } 
    return null; 
} 


@Override 
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { 
      mEmojis = EmojiUtils.insertEmojis(getContext(), getText(), mEmojiconSize); 
} 

而且在那裏使用的KeyEvents文本時,應刪除自定義InputConnection。適用於多種表情符號,因爲選擇是固定的。

@Override 
public InputConnection onCreateInputConnection(EditorInfo outAttrs) { 
    return new EmojiInputConnection(super.onCreateInputConnection(outAttrs), 
      true); 
} 

private class EmojiInputConnection extends InputConnectionWrapper { 

    public EmojiInputConnection(InputConnection target, boolean mutable) { 
     super(target, mutable); 
    } 


    @Override 
    public boolean deleteSurroundingText(int beforeLength, int afterLength) { 
     if (beforeLength == 1 && afterLength == 0) { 
      return sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)) 
        && sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL)); 
     } else{ 
      int cursorPos = getSelectionStart(); 
      int cursorEnd = getSelectionEnd(); 
      if(cursorEnd == cursorPos && beforeLength == 2 && afterLength == 0){ 
       return sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)) 
         && sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL)); 
      } 
     } 

     return super.deleteSurroundingText(beforeLength, afterLength); 
    } 

} 

其中EmojiTupel是來自另一個類的字符串中的索引的包裝。

public static class EmojiTupel{ 
       public int start, end; 
       public EmojiTupel(int start, int end){ 
         this.start = start; 
         this.end = end; 
       } 
} 
0

這是因爲軟鍵盤的工作原理。很少有人使用關鍵事件。他們更可能使用deleteSurroundingText刪除新聞。你需要做的是覆蓋你的視圖的inputConnection,並覆蓋deleteSurrounding文本,這樣如果在刪除區域中有表情符號,它將刪除整個表情符號而不僅僅是單個字符。

+0

謝謝。 Postet源代碼作爲解決問題的答案。 – TeeAttack42