我的软键盘连接和ankushsachdeva的emojicon键盘的自定义实现与emojione图像有问题。
https://github.com/ankushsachdeva/emojicon
当我以UTF 16格式插入一些较新的Emojis时,就像这个家庭表情一样:http://www.unicode.org/Public/emoji/2.0//emoji-zwj-sequences.txt
或具有不同肤色的笑脸。我的ImageSpans正确地替换了unicode。
当我按下表情符号键盘中的特殊后退按钮时,它会通过调用键事件来删除完整的表情符号。
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);
}
});
但问题出在这里:
当我尝试按下默认键盘上的键盘退格键时,它会删除char中的char而不是整个表情符号。
因为较新的笑脸由多个chars / unicode代理组成,我必须多次按退格按钮并面对一些奇怪的其他笑脸组合。
当我尝试通过长按EditText来选择表情符号时,甚至有一些奇怪的行为,它只选择那个较长表情符号的第一个字符,但标记整个ImageSpan。
有任何建议如何解决?
答案 0 :(得分:1)
感谢Gabe Sechan的帮助。
这是一些对我有用的代码。随意添加改进。
修复Custom 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);
}
还有在应删除Text时使用KeyEvents的Custom InputConnection。适用于多个Emojis,因为选择是固定的。
@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是来自另一个类的String中索引的包装器。
public static class EmojiTupel{
public int start, end;
public EmojiTupel(int start, int end){
this.start = start;
this.end = end;
}
}
答案 1 :(得分:0)
这是因为软键盘的工作原理。他们中很少使用关键事件。他们更有可能使用deleteSurroundingText进行删除操作。您需要做的是覆盖视图的inputConnection,并覆盖deleteSurrounding文本,这样如果删除区域中有表情符号,它将删除整个表情符号,而不仅仅是单个字符。