본 포스팅은 DroidKaigi 2017 ~ トークアプリで絵文字を実装した話 을 기본으로 번역하여 작성했습니다
제 일본어 실력으로 인하여 오역이나 오타가 발생할 수 있습니다.
DroidKaigi 2017 @futabooo
futabooo (ふたぶー)
FantasyEarth Zero, s.CRY.ed
pairs | COUPLES |
앨범, 기념일, 스케줄을 하나로
두 사람의 추억을 간단하게 공유
Talk
Talk
Talk
이모티콘
앱 자체 이모티콘 도입 전
◆ Couples에 대한 의견・감상
이미지처럼 이모티콘이 표시되지 않습니다! 내가 보낸 것은 표시되는 것 같습니다!
단말이나 통신사의 차이에 따라 제대로 이모티콘 표시가 안된다
자체 이모티콘을 넣자
Couples 자체 이모티콘 도입까지의 흐름
타사 앱 연구
여기서부터 개발 이야기입니다
이모티콘을 표시한다
String 타입
안녕하세요{ { sticon(1,10) } }
오늘은 날씨가 좋네요!{ { sticon(2,20) } }
SpannableString 타입
안녕하세요🐻오늘은 날씨가 좋네요!🌞
TalkMessageToken |
---|
characterStyle: SticonSpan |
beginIndex: int |
endIndex: int |
DynamicDrawableSpan | SticonSpan |
---|---|
draw() | sticon: Drawable |
altText: Sting |
// 표시하고 싶은 문자열
String message = "안녕하세요{ { sticon(1,10) } } 오늘은 날씨가 좋네요!{ { sticon(2,20) } }"
// 어디에 어떤 이모티콘을 표시할지를 유지한 리스트를 얻는다
List<TalkMessageToken> tokenList = TalkMessageHelper.getSticonSpanTokens(message);
// 리스트를 기반으로 문자열에 이모티콘을 대응시켜 그린다
SpannableString spanedMessage = new SpannableString(message);
for (TalkMessageToken t : tokenList) {
spanedMessage.setSpan(t.characterStyle, t.beginIndex, t.endIndex, t.flags);
}
talkView.setText(spanedMessage);
String text = "One, two, { { three } }. Three sir!";
Template tmpl = Mustache.compiler().compile(text);
Map<> data = new HashMap<String, String>();
data.put("three", "five");
System.out.println(tmpl.execute(data));
//result: "One, two, five. Three sir!"
// 정규표현식의 패턴을 작성한다
Pattern STICON = Pattern.compile("\\{\\{sticon\\(.+?\\)\\}\\}");
Pattern IDS = Pattern.compile("(\\d+),(\\d+)");
List<TalkMessageToken> getSticonSpanTokens(String rawText) {
ArrayList<TalkMessageToken> tokens = new ArrayList<>();
// Matcher를 사용해서 패턴에 매치한 부분에 처리한다
Matcher t = STICON.matcher(rawText);
Matcher ids = IDS.matcher("");
while (t.find()) {// { { sticon(1,10) } }와{ { sticon(2,20) } }
matcherIds.reset(t.group());
if (ids.find()) {// (1,10)와(2,20)
TalkMessageToken token = new TalkMessageToken(sticonSpan, t.start(), t.end());
tokens.add(token);
}
}
}
class TalkMessageToken {
public CharacterStyle characterStyle;
public int beginIndex;
public int endIndex;
}
안녕하세요{ { sticon(1,10) } }오늘은 날씨가 좋네요!{ { sticon(2,20) } }
TalkMessageToken | TalkMessageToken |
---|---|
characterStyle = sticonSpan | characterStyle = sticonSpan |
beginIndex = 5 | beginIndex = 32 |
endIndex = 20 | endIndex = 47 |
class SticonSpan extends DynamicDrawableSpan {
Drawable sticon;
String altText;
String rawText;
int stickerId;
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
// 자신이 적용된 string 부분을 sticon으로 치환하여 그린다
}
}
String 타입
안녕하세요{ { sticon(1,10) } }오늘은 날씨가 좋네요!{ { sticon(2,20) } }
SpannableString 타입
안녕하세요🐻오늘은 날씨가 좋네요!🌞
TalkMessageToken |
---|
characterStyle: SticonSpan |
beginIndex: int |
endIndex: int |
DynamicDrawableSpan | SticonSpan |
---|---|
draw() | sticon: Drawable |
altText: Sting |
이모티콘을 복사 & 붙여넣기할 수 있다
SpannableString 타입
안녕하세요{ { sticon(1,10) } }오늘은 날씨가 좋네요!{ { sticon(2,20) } }
-> Copy
->
앱 내부 | 클립보드 |
---|---|
copiedRawText: String | cpoiedAltText: String |
cpoiedAltText: String | |
sticonCpied: boolean |
-> Paste
안녕하세요🐻오늘은 날씨가 좋네요!🌞
안녕하세요(bo)오늘은 날씨가 좋네요!(Sunny)
// 문자열을 앱내에 유지한다
setCopiedText(message);
// 클립보드에 대체 텍스트를 저장
altText = TalkMessageHelper.getAltText(message);
String[] mimetype = {ClipDescription.MIMETYPE_TEXT_PLAIN};
ClipData.Item item = new ClipData.Item(altText);
ClipData cd = new ClipData(new ClipDescription("text",mimetype),item);
ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
cm.setPrimaryClip(cd);
// 복사시의 문자열과 비교한 후에 붙여넣기
@Override public void afterTextChanged(Editable s) {
if (isSticonPasted()) {
// 이모티콘 표시 처리
}
}
SpannableString 타입
안녕하세요{ { sticon(1,10) } }오늘은 날씨가 좋네요!{ { sticon(2,20) } }
-> Copy
->
앱 내부 | 클립보드 |
---|---|
copiedRawText: String | cpoiedAltText: String |
cpoiedAltText: String | |
sticonCpied: boolean |
-> Paste
안녕하세요🐻오늘은 날씨가 좋네요!🌞
안녕하세요(bo)오늘은 날씨가 좋네요!(Sunny)
이모티콘 하나만 보내면 스탬프가 된다
public boolean isSendSticonAsSticker() {
SticonSpan[] tokens =editText.getText().getSpans(0, editText.getText().length(), SticonSpan.class);
if(tokens.length == 1) {
// 이모티콘을 나타내는 문자열이 하나만 입력된 경우
if(tokens[0].getTemplateString().equals(editText.getText())) {
return true;
}
}
// 이모티콘이 하나이지 않은 경우
return false;
}
if (isSendSticonAsSticker()) {
Editable t = editText.getText()
SticonSpan[] spans = t.getSpans(0, t.length(), SticonSpan.class);
// 스탬프를 생성해서 송신
Sticker sticker = new Sticker(spans[0].getSticonId());
sendStamp(sticker);
} else {
// 텍스트 메시지&이모티콘으로 송신
}
시간이 걸린 부분
이모티콘 복사&붙여넣기하면 문자가 짤린다
안녕하세요🐻
오늘은 날씨가 좋네요!🌞
-> Copy
안녕하세요{
{ sticon(1,10) } } 이대로는 mustache의 도중에 짤린다
->
안녕하세요{ { sticon(1,10) } }
복사&붙여넣기를 mustache의 종단까지 늘린다
정리
comments powered by Disqus
Subscribe to this blog via RSS.
LazyColumn/Row에서 동일한 Key를 사용하면 크래시가 발생하는 이유
Posted on 30 Nov 2024