Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

トークアプリで絵文字を実装した話

 トークアプリで絵文字を実装した話

futabooo

March 09, 2017
Tweet

More Decks by futabooo

Other Decks in Programming

Transcript

  1. 2 About me - Lead Engineer at eureka, Inc. -

    Java, Kotlin, Golang, TypeScript, AngularJS - FantasyEarth Zero, s.CRY.ed futabooo futabooo futabooo (ס׋ע٦)
  2. 5 About eureka • Web • Golang, Gin • TypeScript,

    AngularJS • Android • Java, Kotlin • Dagger2, Orma, OkHttp3, Retrofit2, RxKotlin, Picasso, ButterKnife, DataBinding • iOS • Objective-C, Swift • CoreStore, Alamofire, Moya RxSwift, AsyncDisplayKit • Web • PHP, Codeigniter • Android • Java • ActiveAndroid, Volley, OkHttp3, Retrofit2, Socket.IO, RxJava, Glide • iOS • Swift, Objective-C • CoreStore, AFNetworking, SwiftyJSON, SDWebImage, RxSwift, Cartography
  3. 08 About Couples ز٦ؙ ‣ ذؗأزًحإ٦آ ‣ 窩俑㶵 ‣ ن؎أًحإ٦آ

    ‣ 歗⫷ ‣ ⹛歗 ‣ أةٝف ‣ ⡘縧䞔㜠 ‣ 5IJOLJOHPG:PV
  4. 09 About Couples ز٦ؙ ‣ ذؗأزًحإ٦آ ‣ 窩俑㶵 ‣ ن؎أًحإ٦آ

    ‣ 歗⫷ ‣ ⹛歗 ‣ أةٝف ‣ ⡘縧䞔㜠 ‣ 5IJOLJOHPG:PV
  5. ‣ ➬圫׾寸׭׷ ˖ ➭爡،فٔד杝荈窩俑㶵ָ㹋鄲ׁ׸גְ׷׮ ך׾灇瑔ׅ׷ ˖ 堣腉׾峤ְ⳿ׅ ˖ ؙؔٔذ؍ך然钠 ‣

    Ꟛ涪ׅ׷ ˖ ➬圫寸׭ד峤ְ⳿׃׋堣腉ך㹋鄲 15 Couplesಠࣗֆจࣈಋೖ·ͰͷྲྀΕ
  6. ‣ Ⳣ椚ך崧׸ 22 ֆจࣈΛදࣔ͢Δ こんにちは{{sticon(1,10)}}今日はいい天気ですね!{{sticon(2,20)}} TalkMessageToken characterStyle : SticonSpan beginIndex

    : int endIndex : int TalkMessageToken characterStyle : SticonSpan beginIndex : int endIndex : int こんにちは 今日はいい天気ですね! SpannableString型 String型 SticonSpan sticon : Drawable altText : String DynamicDrawableSpan draw() ύʔαʔ
  7. ‣ ॲཧͷྲྀΕ 23 ֆจࣈΛදࣔ͢Δ こんにちは{{sticon(1,10)}}今日はいい天気ですね!{{sticon(2,20)}} TalkMessageToken characterStyle : SticonSpan beginIndex

    : int endIndex : int TalkMessageToken characterStyle : SticonSpan beginIndex : int endIndex : int こんにちは 今日はいい天気ですね! SpannableString型 String型 SticonSpan sticon : Drawable altText : String DynamicDrawableSpan draw() ύʔαʔ
  8. ‣ ॲཧͷྲྀΕ 24 ֆจࣈΛදࣔ͢Δ TalkMessageToken characterStyle : SticonSpan beginIndex :

    int endIndex : int TalkMessageToken characterStyle : SticonSpan beginIndex : int endIndex : int SticonSpan sticon : Drawable altText : String DynamicDrawableSpan draw() こんにちは 今日はいい天気ですね! SpannableString型 こんにちは{{sticon(1,10)}}今日はいい天気ですね!{{sticon(2,20)}} String型 ύʔαʔ
  9. ‣ ॲཧͷྲྀΕ 25 ֆจࣈΛදࣔ͢Δ TalkMessageToken characterStyle : SticonSpan beginIndex :

    int endIndex : int TalkMessageToken characterStyle : SticonSpan beginIndex : int endIndex : int SticonSpan sticon : Drawable altText : String DynamicDrawableSpan draw() こんにちは 今日はいい天気ですね! SpannableString型 こんにちは{{sticon(1,10)}}今日はいい天気ですね!{{sticon(2,20)}} String型 ύʔαʔ
  10. 26 ֆจࣈΛදࣔ͢Δ // 表示したい文字列 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); ‣ ॲཧͷྲྀΕ
  11. 27 ֆจࣈΛදࣔ͢Δ // 表示したい文字列 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); ‣ ॲཧͷྲྀΕ
  12. 28 ֆจࣈΛදࣔ͢Δ // 表示したい文字列 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); ‣ ॲཧͷྲྀΕ
  13. 29 ֆจࣈΛදࣔ͢Δ // 表示したい文字列 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); ‣ ॲཧͷྲྀΕ
  14. 30 ֆจࣈΛදࣔ͢Δ // 表示したい文字列 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); ‣ ॲཧͷྲྀΕ
  15. 31 ֆจࣈΛදࣔ͢Δ // 表示したい文字列 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); ‣ ॲཧͷྲྀΕ
  16. ‣ {{ mustache }} • Logic-less templates • ୯७ͳஔ͖׵͑Λߦ͏ςϯϓϨʔτ •

    Java࣮૷ samskivert/jmustache 32 ֆจࣈΛදࣔ͢Δ 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!"
  17. 33 ֆจࣈΛදࣔ͢Δ 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!" ‣ {{ mustache }} • Logic-less templates • ୯७ͳஔ͖׵͑Λߦ͏ςϯϓϨʔτ • Java࣮૷ samskivert/jmustache
  18. 34 ֆจࣈΛදࣔ͢Δ 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!" ‣ {{ mustache }} • Logic-less templates • ୯७ͳஔ͖׵͑Λߦ͏ςϯϓϨʔτ • Java࣮૷ samskivert/jmustache
  19. 35 ֆจࣈΛදࣔ͢Δ 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!" ‣ {{ mustache }} • Logic-less templates • ୯७ͳஔ͖׵͑Λߦ͏ςϯϓϨʔτ • Java࣮૷ samskivert/jmustache
  20. 36 ֆจࣈΛදࣔ͢Δ 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!" ‣ {{ mustache }} • Logic-less templates • ୯७ͳஔ͖׵͑Λߦ͏ςϯϓϨʔτ • Java࣮૷ samskivert/jmustache
  21. 37 ֆจࣈΛදࣔ͢Δ 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!" ‣ {{ mustache }} • Logic-less templates • ୯७ͳஔ͖׵͑Λߦ͏ςϯϓϨʔτ • Java࣮૷ samskivert/jmustache
  22. 41 ֆจࣈΛදࣔ͢Δ // 正規表現のパターンを作成する 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(matcherTemplate.group());
 if (ids.find()) {// (1,10)と(2,20) TalkMessageToken token = new TalkMessageToken(sticonSpan, t.start(), t.end());
 tokens.add(token); } } } ‣ Ͳ͜ʹͲͷֆจࣈΛදࣔ͢Δ͔อ࣋ͨ͠Ϧετͷऔಘ
  23. 42 ֆจࣈΛදࣔ͢Δ // 正規表現のパターンを作成する 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); } } } ‣ Ͳ͜ʹͲͷֆจࣈΛදࣔ͢Δ͔อ࣋ͨ͠Ϧετͷऔಘ
  24. 43 ֆจࣈΛදࣔ͢Δ // 正規表現のパターンを作成する 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); } } } ‣ Ͳ͜ʹͲͷֆจࣈΛදࣔ͢Δ͔อ࣋ͨ͠Ϧετͷऔಘ
  25. 44 ֆจࣈΛදࣔ͢Δ // 正規表現のパターンを作成する 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); } } } ‣ Ͳ͜ʹͲͷֆจࣈΛදࣔ͢Δ͔อ࣋ͨ͠Ϧετͷऔಘ
  26. 45 ֆจࣈΛදࣔ͢Δ // 正規表現のパターンを作成する 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); } } } ‣ Ͳ͜ʹͲͷֆจࣈΛදࣔ͢Δ͔อ࣋ͨ͠Ϧετͷऔಘ
  27. 46 ֆจࣈΛදࣔ͢Δ // 正規表現のパターンを作成する 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); } } } ‣ Ͳ͜ʹͲͷֆจࣈΛදࣔ͢Δ͔อ࣋ͨ͠Ϧετͷऔಘ
  28. 47 ֆจࣈΛදࣔ͢Δ class TalkMessageToken {
 public CharacterStyle characterStyle;
 public int

    beginIndex;
 public int endIndex; } ‣ TalkMessageToken • Ͳ͜ʹͲΜͳελΠϧΛ౰ͯΔ͔อ࣋͢ΔΫϥε こんにちは{{sticon(1,10)}}今日はいい天気ですね!{{sticon(2,20)}} TalkMessageToken characterStyle = sticonSpan beginIndex = 5 endIndex = 20 TalkMessageToken characterStyle = sticonSpan beginIndex = 32 endIndex = 47
  29. 48 ֆจࣈΛදࣔ͢Δ ‣ TalkMessageToken • Ͳ͜ʹͲΜͳελΠϧΛ౰ͯΔ͔อ࣋͢ΔΫϥε こんにちは{{sticon(1,10)}}今日はいい天気ですね!{{sticon(2,20)}} TalkMessageToken characterStyle =

    sticonSpan beginIndex = 5 endIndex = 20 TalkMessageToken characterStyle = sticonSpan beginIndex = 32 endIndex = 47 class TalkMessageToken {
 public CharacterStyle characterStyle;
 public int beginIndex;
 public int endIndex; }
  30. 49 ֆจࣈΛදࣔ͢Δ ‣ TalkMessageToken • Ͳ͜ʹͲΜͳελΠϧΛ౰ͯΔ͔อ࣋͢ΔΫϥε こんにちは{{sticon(1,10)}}今日はいい天気ですね!{{sticon(2,20)}} TalkMessageToken characterStyle =

    sticonSpan beginIndex = 5 endIndex = 20 TalkMessageToken characterStyle = sticonSpan beginIndex = 32 endIndex = 47 class TalkMessageToken {
 public CharacterStyle characterStyle;
 public int beginIndex;
 public int endIndex; }
  31. 50 ֆจࣈΛදࣔ͢Δ ‣ SticonSpan • ֆจࣈ৘ใΛอ࣋͢ΔΫϥε 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に置換して描画する
 } }
  32. 51 ֆจࣈΛදࣔ͢Δ 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に置換して描画する
 } } ‣ SticonSpan • ֆจࣈ৘ใΛอ࣋͢ΔΫϥε
  33. 52 ֆจࣈΛදࣔ͢Δ ‣ SticonSpan • ֆจࣈ৘ใΛอ࣋͢ΔΫϥε 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に置換して描画する
 } }
  34. 53 ֆจࣈΛදࣔ͢Δ ‣ SticonSpan • ֆจࣈ৘ใΛอ࣋͢ΔΫϥε 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に置換して描画する
 } }
  35. 54 ֆจࣈΛදࣔ͢Δ ‣ SticonSpan • ֆจࣈ৘ใΛอ࣋͢ΔΫϥε 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に置換して描画する
 } }
  36. 55 ֆจࣈΛදࣔ͢Δ 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に置換して描画する
 } } ‣ SticonSpan • ֆจࣈ৘ใΛอ࣋͢ΔΫϥε
  37. 56 ֆจࣈΛදࣔ͢Δ ‣ SticonSpan • ֆจࣈ৘ใΛอ࣋͢ΔΫϥε 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に置換して描画する
 } }
  38. こんにちは 今日はいい天気ですね! 57 ֆจࣈΛදࣔ͢Δ こんにちは{{sticon(1,10)}}今日はいい天気ですね!{{sticon(2,20)}} TalkMessageToken characterStyle : SticonSpan beginIndex

    : int endIndex : int TalkMessageToken characterStyle : SticonSpan beginIndex : int endIndex : int SpannableString型 String型 SticonSpan sticon : Drawable altText : String DynamicDrawableSpan draw() ύʔαʔ ‣ ͓͞Β͍
  39. ‣ ॲཧͷྲྀΕ • ίϐʔ͞ΕͨΒԼهจࣈྻΛΞϓϦ಺Ͱอ࣋͢Δ • ੜςΩετ ʮ͜Μʹͪ͸{{sticon(1,10)}}ʯ • ୅ସςΩετ ʮ͜Μʹͪ͸(bo)ʯ

    • ୅ସςΩετΛΫϦοϓϘʔυʹอଘ͢Δ • Couples֎Ͱͷϖʔετ͸୅ସςΩετදࣔ • ίϐʔ࣌ͷจࣈྻͱൺ্ֱͨ͠Ͱϖʔετ͢Δ 59 ֆจࣈΛίϐʔ&ϖʔετͰ͖Δ
  40. ‣ ॲཧͷྲྀΕ 60 ֆจࣈΛίϐʔ&ϖʔετͰ͖Δ SpannableString型 こんにちは 今日はいい天気ですね! Copy copiedRawText: String

    copiedAltText : String sticonCopied: boolean ΞϓϦ಺ ΫϦοϓϘʔυ copiedAltText : String Paste こんにちは 今日はいい天気ですね! こんにちは(bo)今日はいい天気ですね!(Sunny)
  41. ‣ ॲཧͷྲྀΕ 61 ֆจࣈΛίϐʔ&ϖʔετͰ͖Δ SpannableString型 こんにちは 今日はいい天気ですね! Copy copiedRawText: String

    copiedAltText : String sticonCopied: boolean ΞϓϦ಺ ΫϦοϓϘʔυ copiedAltText : String Paste こんにちは 今日はいい天気ですね! こんにちは(bo)今日はいい天気ですね!(Sunny)
  42. ‣ ॲཧͷྲྀΕ 62 ֆจࣈΛίϐʔ&ϖʔετͰ͖Δ SpannableString型 こんにちは 今日はいい天気ですね! Copy copiedRawText: String

    copiedAltText : String sticonCopied: boolean ΞϓϦ಺ ΫϦοϓϘʔυ copiedAltText : String Paste こんにちは 今日はいい天気ですね! こんにちは(bo)今日はいい天気ですね!(Sunny)
  43. ‣ ॲཧͷྲྀΕ 63 ֆจࣈΛίϐʔ&ϖʔετͰ͖Δ SpannableString型 こんにちは 今日はいい天気ですね! Copy copiedRawText: String

    copiedAltText : String sticonCopied: boolean ΞϓϦ಺ ΫϦοϓϘʔυ copiedAltText : String Paste こんにちは 今日はいい天気ですね! こんにちは(bo)今日はいい天気ですね!(Sunny)
  44. 64 ֆจࣈΛίϐʔ&ϖʔετͰ͖Δ ‣ ॲཧͷྲྀΕ // 文字列をアプリ内に保持する 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()) { // 絵文字表示処理 } }
  45. 65 ֆจࣈΛίϐʔ&ϖʔετͰ͖Δ ‣ ॲཧͷྲྀΕ // 文字列をアプリ内に保持する 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()) { // 絵文字表示処理 } }
  46. 66 ֆจࣈΛίϐʔ&ϖʔετͰ͖Δ ‣ ॲཧͷྲྀΕ // 文字列をアプリ内に保持する 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()) { // 絵文字表示処理 } }
  47. 67 ֆจࣈΛίϐʔ&ϖʔετͰ͖Δ ‣ ॲཧͷྲྀΕ // 文字列をアプリ内に保持する 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()) { // 絵文字表示処理 } }
  48. 68 ֆจࣈΛίϐʔ&ϖʔετͰ͖Δ ‣ ॲཧͷྲྀΕ // 文字列をアプリ内に保持する 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()) { // 絵文字表示処理 } }
  49. ‣ ͓͞Β͍ 69 ֆจࣈΛίϐʔ&ϖʔετͰ͖Δ SpannableString型 こんにちは 今日はいい天気ですね! Copy copiedRawText: String

    copiedAltText : String sticonCopied: boolean ΞϓϦ಺ ΫϦοϓϘʔυ copiedAltText : String Paste こんにちは 今日はいい天気ですね! こんにちは(bo)今日はいい天気ですね!(Sunny)
  50. ‣ ελϯϓͱͯ͠ૹΔ͔Ͳ͏͔൑ఆ͢Δ 72 ֆจࣈ1ݸ͚ͩͰૹΔͱελϯϓʹͳΔ public boolean isSendSticonAsSticker(){
 SticonSpan[] tokens =editText.getText().getSpans(

    0, editText.getText().length(), SticonSpan.class); if(tokens.length == 1){ // 絵文字を表す文字列が1個だけ入力されてる場合
 if(tokens[0].getTemplateString().equals(editText.getText())){
 return true;
 }
 } // 絵文字が1個だけじゃない場合
 return false;
 }
  51. ‣ ελϯϓͱͯ͠ૹΔ͔Ͳ͏͔൑ఆ͢Δ 73 ֆจࣈ1ݸ͚ͩͰૹΔͱελϯϓʹͳΔ public boolean isSendSticonAsSticker(){
 SticonSpan[] tokens =editText.getText().getSpans(

    0, editText.getText().length(), SticonSpan.class); if(tokens.length == 1){ // 絵文字を表す文字列が1個だけ入力されてる場合
 if(tokens[0].getTemplateString().equals(editText.getText())){
 return true;
 }
 } // 絵文字が1個だけじゃない場合
 return false;
 }
  52. ‣ ελϯϓͱͯ͠ૹΔ͔Ͳ͏͔൑ఆ͢Δ 74 ֆจࣈ1ݸ͚ͩͰૹΔͱελϯϓʹͳΔ public boolean isSendSticonAsSticker(){
 SticonSpan[] tokens =editText.getText().getSpans(

    0, editText.getText().length(), SticonSpan.class); if(tokens.length == 1){ // 絵文字を表す文字列が1個だけ入力されてる場合
 if(tokens[0].getTemplateString().equals(editText.getText())){
 return true;
 }
 } // 絵文字が1個だけじゃない場合
 return false;
 }
  53. ‣ ελϯϓͱͯ͠ૹΔ͔Ͳ͏͔൑ఆ͢Δ 75 ֆจࣈ1ݸ͚ͩͰૹΔͱελϯϓʹͳΔ public boolean isSendSticonAsSticker(){
 SticonSpan[] tokens =editText.getText().getSpans(

    0, editText.getText().length(), SticonSpan.class); if(tokens.length == 1){ // 絵文字を表す文字列が1個だけ入力されてる場合
 if(tokens[0].getTemplateString().equals(editText.getText())){
 return true;
 }
 } // 絵文字が1個だけじゃない場合
 return false;
 }
  54. ‣ ελϯϓͱͯ͠ૹΔ͔Ͳ͏͔൑ఆ͢Δ 76 ֆจࣈ1ݸ͚ͩͰૹΔͱελϯϓʹͳΔ public boolean isSendSticonAsSticker(){
 SticonSpan[] tokens =editText.getText().getSpans(

    0, editText.getText().length(), SticonSpan.class); if(tokens.length == 1){ // 絵文字を表す文字列が1個だけ入力されてる場合
 if(tokens[0].getTemplateString().equals(editText.getText())){
 return true;
 }
 } // 絵文字が1個だけじゃない場合
 return false;
 }
  55. ‣ ελϯϓΛૹΔ 77 ֆจࣈ1ݸ͚ͩͰૹΔͱελϯϓʹͳΔ 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 { // テキストメッセージ&絵文字として送信 }
  56. ‣ ελϯϓΛૹΔ 78 ֆจࣈ1ݸ͚ͩͰૹΔͱελϯϓʹͳΔ 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 { // テキストメッセージ&絵文字として送信 }
  57. ‣ ελϯϓΛૹΔ 79 ֆจࣈ1ݸ͚ͩͰૹΔͱελϯϓʹͳΔ 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 { // テキストメッセージ&絵文字として送信 }
  58. ‣ ελϯϓΛૹΔ 80 ֆจࣈ1ݸ͚ͩͰૹΔͱελϯϓʹͳΔ 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 { // テキストメッセージ&絵文字として送信 }