Android: keyboard no longer covers editor fields (S-19, S-15, S-6)

The recurring, category and account editors drew their scrolling body
inside KvittScaffold with only the scaffold padding, so with adjustResize
and edge-to-edge the keyboard overlaid the content and a focused field
(S-19 day of month, notes) stayed hidden. Each body now applies
padding(padding).consumeWindowInsets(padding).imePadding(), as S-7 does
with imePadding(): the viewport shrinks above the keyboard and Compose's
scroll container keeps the focused text field in view. Consuming the
scaffold padding first stops the navigation inset (or the S-19 keypad
bottom bar) from being counted twice.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
This commit is contained in:
2026-10-21 20:24:14 +02:00
parent 3778f5fa81
commit 05ec3f3f16
3 changed files with 12 additions and 2 deletions
@@ -8,8 +8,10 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@@ -165,7 +167,7 @@ private fun EditorForm(ui: AccountEditorUi, me: User, partner: User, actions: Ac
if (ui.loaded && ui.editing == null && ui.online) focus.requestFocus()
}
Column(
Modifier.fillMaxSize().padding(padding).verticalScroll(rememberScrollState()).padding(horizontal = spacing.gutter, vertical = spacing.s1),
Modifier.fillMaxSize().padding(padding).consumeWindowInsets(padding).imePadding().verticalScroll(rememberScrollState()).padding(horizontal = spacing.gutter, vertical = spacing.s1),
verticalArrangement = Arrangement.spacedBy(KvittDimens.dialogGap),
) {
if (!ui.online) {
@@ -5,8 +5,10 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
@@ -122,6 +124,8 @@ fun CategoryEditorContent(state: CategoryEditorState?, actions: CategoryEditorAc
Modifier
.fillMaxSize()
.padding(padding)
.consumeWindowInsets(padding)
.imePadding()
.verticalScroll(rememberScrollState())
.padding(horizontal = KvittTheme.spacing.gutter, vertical = KvittTheme.spacing.s2),
verticalArrangement = Arrangement.spacedBy(KvittTheme.spacing.detailGap),
@@ -8,9 +8,11 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
@@ -186,7 +188,9 @@ fun RecurringEditorContent(state: RecurringEditorState?, actions: RecurringEdito
) { padding ->
if (state == null) return@KvittScaffold
ProvideHousehold(state.options.me, state.options.partner) {
EditorBody(state, actions, Modifier.padding(padding))
// The keyboard shrinks the scrolling body (adjustResize, as S-7) so a focused field stays above it; consuming the
// scaffold padding first keeps the bottom bar or navigation inset from counting twice.
EditorBody(state, actions, Modifier.padding(padding).consumeWindowInsets(padding).imePadding())
when (state.sheet) {
EditorSheet.Category -> ModalBottomSheet(actions.onCloseSheet) {
CategoryGrid(state.options.categories, state.form.categoryId, { actions.onCategory(it.id) }, Modifier.padding(KvittTheme.spacing.gutter))