Upgrade to Pro — share decks privately, control downloads, hide ads and more …

카카오톡 미니 이모티콘 in Android

kakao
November 01, 2024

카카오톡 미니 이모티콘 in Android

#Android #미니이모티콘

카카오톡에 새롭게 출시된 미니이모티콘의 안드로이드에서의 개발과정을 소개합니다.

Span 을 이용하여 미니이모티콘을 렌더링하고 비트맵을 관리하는 방법 및
서로 다른 미니이모티콘의 동작 싱크를 맞추는 방법을 설명합니다.

미니이모티콘이 키보드에서 클릭 되어 입력되어 입력창에 들어가는 과정과 InputFilter, TextWatcher 로 입력창에서의 요구 사항을 달성할 수 있었던 경험 및 만났던 어려움과 극복했던 과정들을 공유하고자 합니다.

발표자 : dante.won, dale.band
카카오톡 안드로이드 메시지팀에서 이모티콘 서비스를 개발하고있는 데일입니다.
카카오톡 안드로이드 메시지팀에서 이모티콘 서비스를 개발하고있는 단테입니다.

kakao

November 01, 2024
Tweet

More Decks by kakao

Other Decks in Programming

Transcript

  1. class MiniEmoticonSpan(): ReplacementSpan() { private var currentBitmap: Bitmap? = null

    fun setBitmap(bitmap: Bitmap) { currentBitmap = bitmap.copy() bitmapChanged() // invalidate } override fun draw(canvas: Canvas) { val bitmap = currentBitmap ?: return canvas.drawBitmap(bitmap, paint) } }
  2. class MiniEmoticonSpan(): ReplacementSpan() { private var currentBitmap: Bitmap? = null

    fun setBitmap(bitmap: Bitmap) { currentBitmap = bitmap.copy() bitmapChanged() // invalidate } override fun draw(canvas: Canvas) { val bitmap = currentBitmap ?: return canvas.drawBitmap(bitmap, paint) } }
  3. 5FYU8BUDIFS EditText৬ э਷ ఫझ౟ ੑ۱ ೙٘ীࢲ ࢎਊ੗о ੑ۱ೞח ղਊਸ पदрਵ۽

    х૑ೞҊ, Ӓ ߸ചܳ ୶੸ೞח ੋఠಕ੉झ. public interface TextWatcher { // ఫझ౟о ߸҃غӝ੹ী ഐ୹ public void beforeTextChanged(CharSequence s, int start, int count, int after); // ఫझ౟о ߸҃ؼ ٸ ഐ୹ public void onTextChanged(CharSequence s, int start, int before, int count); // ఫझ౟о ߸҃ػ റ ഐ୹ public void afterTextChanged(Editable s); }
  4. ݽٚ޷פ੉ݽ౭௑੤ࢤ CFGPSF5FYU$IBOHFEद੼ী૑ਕ૓޷פ੉ݽ౭௑ઁѢ  TUBSUఫझ౟߸҃੉ੌযդ૑੼  DPVOU૑ਕ૓ఫझ౟ӡ੉ override fun beforeTextChanged(s: CharSequence?,

    start: Int, count: Int, after: Int) { val spans = (s as? Spanned)?.getSpans(start, start + count) ?: return miniEmoticonSpans.removeAll(spans) }
  5. sealed class State { open fun getInputFilter: List<InputFilter> = emptyList()

    class Normal: State { override fun getInputFilter = listOf( MiniEmoticonInputFilter() ) } class Reply: State { override fun getInputFilter = listOf( MiniEmoticonInputFilter(), LengthFilter() ) } /* ... */ }
  6. গפݫ੉࣌੉ۆ ⏯ %FMBZ ⏯ %FMBZ ⏯ %FMBZ ⏯ %FMBZ ⏯

    %FMBZ וܻѱࠄ׮ݶ গפݫ੉࣌਷೐ۨ੐ਸࠁৈ઱ҊEFMBZܳ઱Ҋ೐ۨ੐ਸࠁৈ઱Ҋೞח೯ਤ੄߈ࠂ੉׮ গפݫ੉࣌ब೒௏٘
  7. ब೒ೠ௏٘חزद੤ࢤীࢲޙઁоߊࢤೡࣻ੓਺ п4QBO݃׮ 
 EFDPEF৬ESBX੄ 
 Ѧܻחदр੉э૑ঋইࢲ 
 ޷ࣁೠର੉оߊࢤೣ গפݫ੉࣌زউदр੄൒ܴ গפݫ੉࣌द੘

    EFDPEF৬ESBXীࣗਃػदр GSBNF%FMBZ GSBNF GSBNF GSBNF GSBNF GSBNF GSBNF GSBNF GSBNF GSBNF੉੹ജغחद੼ীрӓ੉੓਺ গפݫ੉࣌ब೒௏٘ গפݫ੉࣌ब೒௏٘
  8. .BJO 5ISFBE t݈ೂࢶױਤ۽ޘযࢲ 
 ߔӒۄ਍٘ॳۨ٘ীਤ੐ #BDLHSPVO E 
 5ISFBE t௏ܖ౯MBVODI৬

    
 DBODFM਷աীѱݐѹu ୭੸ച੹ۚӒܛೝೞৈগפݫ੉࣌௏ܖ౯ਸ-BVODI$BODFM೧ࠁ੗ زदীগפݫ੉࣌೧ঠೞח݈ೂࢶױਤ۽Ӓܛೝೞৈ-BVODI$BODFMਸ੹׸ೞחॳۨ٘ী੹׳ 
 ೠചݶী޷פ੉ݽ౭௑਷ࣻߔѐঀ੓ਸࣻ੓যب݈ೂࢶ਷ࣻѐ߆ীহ਺ ޷פ੉ݽ౭௑ࣻߔѐঀ੓׮ݶ #BDLHSPVO E5ISFBE ޷פ੉ݽ౭௑ޘ਺੄੉޷૑۽٘௒ߔ୊ܻ߂ 
 গפݫ੉࣌௏ܖ౯ਃ୒ ஂࣗ׸׼ п޷פ੉ݽ౭௑੄ 
 ٣௏٬গפݫ੉࣌׸׼
  9. 2"