Skip to content

wanted-preonboarding-hoyahozz/android-wanted-CustomKeyboardApp

 
 

Repository files navigation

📖 Summary

  • 레이아웃 & 사용자 인터페이스를 구현합니다.
  • InputMethodService 를 활용하여 어느 앱에서나 작동하는 두벌식 한글 키보드를 구현합니다.
  • 키보드에 클립보드와 단축키 기능을 구현합니다.

👨‍👨‍👦‍👦 Members

김정호 박규림 박인아 이현섭 임수진
김정호 박규림 박인아 이현섭 임수진

🤝 Convention

📚 Branch

  • {behavior}/issue-{number}-{something}
  • e.g. : feature/issue-007-data-module

🤔 Issue

  • [{behavior}] {something}
  • e.g. : [FEATURE] 프로젝트 세팅

🤲 Pull Request

  • [ISSUE-{number}] {something}
  • e.g. : [ISSUE-007] 데이터 모듈 추가
  • 문장 단위가 아닌, 단어 단위로 제목을 작성합니다.

😊 Commit

  • feat - {something} : 새로운 기능을 추가했을 때
  • fix - {something} : 기능 중 버그를 수정했을 때
  • design - {something} : 디자인 일부를 변경했을 때
  • refactor - {something} : 코드를 재정비 하였을 때
  • chore - {something} : 빌드 관련 업무를 수정하거나 패키지 매니저를 수정했을 때
  • docs - {something} : README와 같은 문서를 변경했을 때
  • 문장 단위가 아닌, 단어 단위로 제목을 작성합니다.

⌨️ Coding

⚙️ Tech Stack

Clean Architecture, Multi-Module, MVVM, Kotlin, Hilt, Coroutine, Room, Lifecycle, Databinding, Livedata, Timber

✍️ Implementation

김정호

프로젝트 베이스 구축

image

  • Clean Architecture 를 주요 아키텍처 패턴으로 채택 및 구현, 레이어별 모듈 구성
  • Presentation 모듈의 경우 MVVM 패턴에 따라 베이스 구현
  • Hilt 모듈 구현
  • Room 데이터베이스 설계 및 구축
  • 규격화된 폰트 적용을 위해 폰트 리소스 구현

메인 페이지 UI 구현

UI

  • 제공된 디자인 시스템에 따라 UI 구현
  • 버튼 클릭 시 ripple 이펙트가 나타나도록 구현
  • 반응형으로 모든 기기에서 동일하게 보여지도록 구현
  • 다이얼로그 UI 구현

이현섭

KakaoTalk_20221013_234717532.mp4
  • 기본적인 키보드 ui
private lateinit var qwertyKeyboardLayout: LinearLayout
    private val qwertyMainKeyboardText = arrayOf(
        arrayOf("1", "2", "3", "4", "5", "6", "7", "8", "9", "0"),
        arrayOf("", "", "", "", "", "", "", "", "", ""),
        arrayOf("", "", "", "", "", "", "", "", ""),
        arrayOf(context.getString(R.string.key_shift), "", "", "", "", "", "", "", context.getString(R.string.key_back)),
        arrayOf(
            context.getString(R.string.key_special),
            context.getString(R.string.key_short),
            ",",
            context.getString(R.string.key_space),
            ".",
            context.getString(R.string.key_enter)
        )
    )
    private val qwertySubKeyboardText = arrayOf(
        arrayOf("", "", "", "", "", "/", "<", ">", "", ""),
        arrayOf("!", "@", "#", "%", "^", "&", "*", "(", ")"),
        arrayOf("", "-", "\'", "\"", ":", ";", ",", "?")
    )
  • 모든앱에 사용하게 만들기

manifest

<service
            android:name=".presentation.keyboard.KeyBoardService"
            android:enabled="true"
            android:exported="true"
            android:label="MyKeyboard"
            android:permission="android.permission.BIND_INPUT_METHOD">
            <meta-data
                android:name="android.view.im"
                android:resource="@xml/xml"/>

            <intent-filter>
                <action android:name="android.view.InputMethod"/>
            </intent-filter>
        </service>
  • 쉬프트 키 눌럿을 때 구현
private fun changeCaps() {
        for (keyNum in qwertyMainKeyboardText[SHIFT_CHANGE_LINE].indices) {
            val layout = layoutLines[SHIFT_CHANGE_LINE].children.toList()
            val mainKeyText = layout[keyNum].findViewById<TextView>(R.id.main_key_text)

            if (isCaps) {
                ...
						}
        isCaps = !isCaps
    }
  • 해당 ui에서 글씨를 바꾸게 했습니다.

박규림

  • CustomKeyboard 앱에서 작동 시연
android-wanted-CustomKeyboardApp_2022-10-14-00-55-19.mp4
  • 다른 앱에서 작동 시연
NAVER_2022-10-14-00-55-39.mp4
  • 이중 자음, 모음 판별을 위한 확장 함수
  • DoubleEnableExtension.kt
// 이중 모음 판별
fun Char.isDoubleVowelEnable(c: Char): Char {
    when(this) {
        '' -> {
            if (c == '') return ''
            if (c == '') return ''
            if (c == '') return ''
            return ' '
        }

        '' -> {
            if (c == '') return ''
            if (c == '') return ''
            if (c == '') return ''
            return ' '
        }

        '' -> {
            if (c == '') return ''
            return ' '
        }

        else -> return ' '
    }
}

// 이중 자음 판별
fun Char.isDoubleConsonantEnable(c: Char): Char {
  // 생략 
}
  • 한글 키보드 입력 상태 분류
  • InputState.kt
enum class InputState {
    NULL, 
    CHO,  
    CHOJUNG,
    CHOJUNGJONG
}
  • Custom Keyboard으로 입력받은 한글을 조합
  • InputMethodService로 사용자가 텍스트를 입력하면 InputConnection 인스턴스를 사용하여 텍스트를 전달

스크린샷 2022-10-14 오후 12 41 10

스크린샷 2022-10-14 오후 12 41 17

스크린샷 2022-10-14 오후 12 41 23

스크린샷 2022-10-14 오후 12 41 44

  • KoreaLanguageMaker.kt
private var choSung: Char = MIN_VALUE
private var jungSung: Char = MIN_VALUE
private var jongSung: Char = MIN_VALUE

private val choSungList: List<Int> = listOf(0x3131, 0x3132, 0x3134, 0x3137, 0x3138, 0x3139, 0x3141,0x3142, 0x3143, 0x3145, 0x3146, 0x3147, 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e)
private val jungSungList:List<Int> = listOf(0x314f, 0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f, 0x3160, 0x3161, 0x3162, 0x3163)
private val jongSungList:List<Int> = listOf(0x0000, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, 0x3140, 0x3141, 0x3142, 0x3144, 0x3145, 0x3146, 0x3147, 0x3148, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e)

fun makeHangul(): Char { // 한 글자 완성
	if (inputState == InputState.NULL) {
	  return MIN_VALUE
  }
  if (inputState == InputState.CHO) {
	return choSung
  }
  val choIndex = choSungList.indexOf(choSung.code)
  val junIndex = jungSungList.indexOf(jungSung.code)
  val jonIndex = jongSungList.indexOf(jongSung.code)

  val makeResult = 0xAC00 + 28 * ((21 * choIndex) + junIndex) + jonIndex
  return makeResult.toChar()
}

박인아

실행영상

Screen_Recording_20221014-130106_KeyboardTest.mp4

About

원티드 프리온보딩 안드로이드 기업과제

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Kotlin 100.0%