๊ฐœ๋ฐœ ์ผ์ง€ ๐Ÿ’ป/๊ธฐํƒ€

[Android] Modifier.imePadding() ๊น”๋”ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ

interfacer_han 2025. 5. 3. 13:54

#1 ๊ฐœ์š”

Modifier.imePadding()์„ ํ†ตํ•ด์„œ, BottomBar๊ฐ€ ๊น”๋”ํ•˜๊ฒŒ ๋™์ž‘ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ์‹œํ–‰์ฐฉ์˜ค๋ฅผ ๊ธฐ๋กํ–ˆ๋‹ค.

 

#2 ์‹œํ–‰์ฐฉ์˜ค 1

#2-1 ์ฝ”๋“œ

Scaffold(
    modifier = Modifier.fillMaxSize(),
    topBar = {
        MainTopBar()
    }
) { innerPadding ->
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(innerPadding)
    ) {
        MainContent(
            modifier = Modifier
                .fillMaxWidth()
                .weight(1f)
        )
        MainBottomBar(
            modifier = Modifier
                .fillMaxWidth()
                .background(Color.LightGray)
                .padding(8.dp)
        )
    }
}

๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๋‹ค. MainBottomBar()๋ฅผ Scaffold์˜ ํ”„๋กœํผํ‹ฐ์— ๋„ฃ์ง€ ์•Š์€ ์ด์œ ๋Š”, BottomSheetScaffold()๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ๋‹ค. BottomSheetScaffold()๋Š” BottomBar๋ฅผ ๋ฐ›๋Š” ํ”„๋กœํผํ‹ฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค.

 

#2-2 ์Šคํฌ๋ฆฐ์ƒท

TextField์˜ ์•„๋ž˜์ชฝ 8.dp ํŒจ๋”ฉ์ด ๊ฐ€๋ ค์ง„๋‹ค. ์™œ๋ƒํ•˜๋ฉด, ๊ฐ€์ƒํ‚ค๋ณด๋“œ(ime)๊ฐ€ TextField๋ฅผ ๋ฐ€์–ด์˜ฌ๋ ธ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. TextField์˜ ์•„๋ž˜์ชฝ ํŒจ๋”ฉ์€ TextField๋กœ ์ทจ๊ธ‰๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ime๊ฐ€ ๋ฐ€์ง€ ์•Š๊ณ  ๊ทธ๋ƒฅ ๊ฐ€๋ ค๋ฒ„๋ฆฐ๋‹ค. ๋‚˜๋Š” ์ด ๋ถ€๋ถ„์ด ๋งˆ์Œ์— ๋“ค์ง€ ์•Š์•˜๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ Scaffold์˜ topBar ๋˜ํ•œ ๋ฐ€๋ ค ์˜ฌ๋ผ๊ฐ€๋Š”๊ฒŒ ์‹ซ์—ˆ๋‹ค.

 

#3 ์‹œํ–‰์ฐฉ์˜ค 2

#3-1 ์ฝ”๋“œ

Scaffold(
    modifier = Modifier
        .fillMaxSize()
        .imePadding(), /* ์ถ”๊ฐ€! */
    topBar = {
        MainTopBar()
    }
) { innerPadding ->
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(innerPadding)
    ) {
        MainContent(
            modifier = Modifier
                .fillMaxWidth()
                .weight(1f)
        )
        MainBottomBar(
            modifier = Modifier
                .fillMaxWidth()
                .background(Color.LightGray)
                .padding(8.dp)
        )
    }
}

Scaffold์˜ modifier์— Modifier.imePadding()์„ ์ถ”๊ฐ€ํ–ˆ๋‹ค. ime๋งŒํผ์˜ ํŒจ๋”ฉ์„ ์คŒ์œผ๋กœ์จ Scaffold๊ฐ€ ime์— ์˜ํ•ด ๋ฐ€๋ ค ์˜ฌ๋ผ๊ฐ€๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ, Scaffold์˜ ๋†’์ด๋ฅผ ์ค„์—ฌ ime์„ ์œ„ํ•œ ๊ณต๊ฐ„์„ ๋น„์›Œ๋‘๊ฒŒ ๋งŒ๋“  ๊ฒƒ์ด๋‹ค.

 

#3-2 ์Šคํฌ๋ฆฐ์ƒท

์Šคํฌ๋ฆฐ์ƒท์œผ๋กœ๋ณด๋ฉด ๊น”๋”ํ•˜์ง€๋งŒ, ๋ฌธ์ œ๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์ด๋‹ค. ์•„๋ž˜ ๋™์˜์ƒ์„ ๋ณด์ž.

 

#3-3 ๋™์˜์ƒ

๋ญ”๊ฐ€ Compose Runtime๊ณผ ์กฐํ™”๋ฅผ ์ด๋ฃจ์ง€ ๋ชปํ•˜๊ณ  ์žˆ๋‹ค. #2-2์—์„œ ๋ณธ ์‹œ์Šคํ…œ์ ์œผ๋กœ ime๊ฐ€ TextField๋ฅผ ๋ฐ€๊ณ  ์˜ฌ๋ผ๊ฐ€๋Š” ๋™์ž‘๊ณผ์˜ ์ถฉ๋Œ์ด ์ผ์–ด๋‚œ ๋ชจ์–‘์ƒˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด topBar๊ฐ€ ๋ช‡ ํ”„๋ ˆ์ž„ ๋™์•ˆ์€ ์‹œ์Šคํ…œ์ฐฝ์„ ๋šซ๊ณ  ์˜ฌ๋ผ๊ฐ€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค (ํŒจ๋”ฉ์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ๊ทธ๋Ÿฐ ์ผ์ด ์ผ์–ด๋‚  ์ˆœ ์—†๋‹ค). ์ด ๊ธฐ๋ณธ ๋™์ž‘์„ ์ปจํŠธ๋กคํ•ด์•ผ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

 

#4 ํ•ด๊ฒฐ

#4-1 ์ฝ”๋“œ

...

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)
        setContent {
            ...
        }
    }
}

window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)์„ ํ†ตํ•ด์„œ, ์ฐฝ(Window)์ด ime ํ˜ธ์ถœ์— ์›€์ง์ด์ง€ ์•Š๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค. ์ฆ‰ #3-3์˜ ๊ธฐ๋ณธ ๋™์ž‘์„ ์ œ๊ฑฐํ•œ ๊ฒƒ์ด๋‹ค.

 

#4-2 ๋™์˜์ƒ

๊น”๋”ํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

 

#5 ๊ตฌ์กฐ ๊ณต๋ถ€ - Window

ViewGroup ์ดํ•˜์˜ ์ด๋ฏธ์ง€ ์ถœ์ฒ˜: https://developer.android.com/develop/ui/views/layout/declaring-layout

Window์™€ Activity์˜ 1:1 ๊ด€๊ณ„

ํ•˜๋‚˜์˜ Activity๋Š” ํ•˜๋‚˜์˜ Window ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ํ™”๋ฉด์„ ํ‘œ์‹œํ•œ๋‹ค. ํ•˜๋‚˜์˜ Activity๊ฐ€ ํ•˜๋‚˜์˜ Window ๊ฐ์ฒด์— 1:1 ๋งค์นญ๋œ๋‹ค. Window๋Š” ๋ทฐ ๊ณ„์ธต ๊ตฌ์กฐ์˜ ์ตœ์ƒ์œ„ ์ปจํ…Œ์ด๋„ˆ์ธ DecorView๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.

 

Window๋Š” ๋ฒ”์šฉ์ ์ธ ๋‹จ์œ„

๊ทธ๋ ‡๋‹ค๊ณ  Window๊ฐ€ Activity์˜ ์ „์šฉ ๊ฐœ๋…์ธ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. Window๋Š” UI๋ฅผ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•œ ๋‹จ์œ„์ผ ๋ฟ์ด๊ณ , ์ด Window๋Š” ๋‹ค์–‘ํ•œ ์ปดํฌ๋„ŒํŠธ์—์„œ ์‚ฌ์šฉ๋œ๋‹ค. ๊ฐ€๋ น Toast ๋ฉ”์‹œ์ง€, Dialog ๋“ฑ๋„ ํ•˜๋‚˜์˜ Window๋ฅผ ๋ณด์œ ํ•œ๋‹ค. WindowManager๋ฅผ ํ†ตํ•ด์„œ (Toast ๋ฉ”์‹œ์ง€๋‚˜ Dialog ๋“ฑ์˜) Window๋ฅผ ํ™”๋ฉด์— ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ œ๊ฑฐํ•ด๋ณธ ๊ธฐ์–ต์ด ์žˆ์„ ๊ฒƒ์ด๋‹ค.

 

WindowInsets

WindowInsets๋Š” ์ด๋ฏธ ํ‘œ์‹œ๋œ Window ์•ˆ์˜ View๋“ค์ด ์‹œ์Šคํ…œ UI๋กœ๋ถ€ํ„ฐ ์นจ๋ฒ”(inset)๋‹นํ•œ ์˜์—ญ์„ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ •๋ณด๋ฅผ ๋‹ด์€ ํด๋ž˜์Šค๋‹ค. ์ƒํƒœ๋ฐ”๋‚˜ ๋„ค๋น„๊ฒŒ์ด์…˜๋ฐ”๊ฐ€ ์˜ˆ๋กœ ๋“ค ์ˆ˜ ์žˆ๋‹ค. Inset์€ ๋ช…์‚ฌ๋กœ๋Š” '์‚ฝ๋„'์˜ ์˜๋ฏธ๋‹ค. '์‚ฝ๋„'๋ž€, ํฐ ์ง€๋„ ์†์— ์žˆ๋Š” ์ž‘์€ ์ง€๋„๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ์šฐ๋ฆฌ๋‚˜๋ผ ์ „๋„ ์† ์„๋ฆ‰๋„ใ†๋…๋„๋ฅผ ๋– ์˜ฌ๋ฆฌ๋ฉด ๋œ๋‹ค. ์„๋ฆ‰๋„ใ†๋…๋„๋Š” ์ข…์ด์˜ ์ž๋ฆฌ๊ฐ€ ๋ถ€์กฑํ•ด์„œ ์‚ฝ๋„๋กœ ํ‘œ์‹œํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.

 

๋งํฌ ๋ชจ์Œ

๊ณต์‹ ๋ฌธ์„œ์˜ ๋งํฌ๋‹ค.

 

#6 ์™„์„ฑ๋œ ์•ฑ (์†Œ์Šค ์ฝ”๋“œ)

 

android-practice/playground/ImePadding at master · Kanmanemone/android-practice

Contribute to Kanmanemone/android-practice development by creating an account on GitHub.

github.com

์ „์ฒด ์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด ์—ฌ๊ธฐ์„œ ๋‹ค์šด๋กœ๋“œํ•˜์ž.