UI/UX: Preserve asset-editor drafts during recompose (#6193)

* Preserve asset-editor drafts and handle the keyboard

Keep the asset name, URL, and delete-confirmation visibility in saveable Compose state so activity recreation does not discard an unfinished edit. Key the state by asset identity and initial field values.

Make the form vertically scrollable, consume the Scaffold padding, and apply IME padding so its fields remain reachable when the keyboard reduces the available height. Extract these presentation changes from local/talkback-all-10 without changing accessibility labels, deletion wording, or asset-save validation order.

* Resize the asset editor when the keyboard opens

Declare stateUnchanged|adjustResize for UserAssetUrlActivity, matching the other editor activities. Without an explicit resize policy, opening the IME in landscape pans the entire window and moves the toolbar Save action off-screen despite the scrollable Compose form.

Verified on Android 13 Pixel 6a: rotate with an unsaved draft, reopen the landscape keyboard, scroll between fields, edit the first field, save without hiding the keyboard, and reopen persisted values. Portrait keyboard and Save also pass. Debug assembly succeeded.
This commit is contained in:
eliotcougar authored and nerpa committed 2026-09-14 16:53:35 +03:00
1 parent b7c69486bf
commit 6400d33b87
2 files changed
+12 -4

No files matched your search

+1
View File
@@ -157,6 +157,7 @@
android:exported="false" />
<activity
android:name=".ui.userasset.UserAssetUrlActivity"
android:windowSoftInputMode="stateUnchanged|adjustResize"
android:exported="false" />
<activity
@@ -4,15 +4,19 @@ import android.os.Bundle
import android.text.TextUtils
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
@@ -138,9 +142,9 @@ fun UserAssetUrlScreen(
onSave: (String, String) -> Boolean,
onDelete: () -> Unit
) {
var remarks by remember { mutableStateOf(initialRemarks) }
var url by remember { mutableStateOf(initialUrl) }
var showDeleteConfirm by remember { mutableStateOf(false) }
var remarks by rememberSaveable(editAssetId, initialRemarks) { mutableStateOf(initialRemarks) }
var url by rememberSaveable(editAssetId, initialUrl) { mutableStateOf(initialUrl) }
var showDeleteConfirm by rememberSaveable(editAssetId) { mutableStateOf(false) }
Scaffold(
contentWindowInsets = WindowInsets(0),
@@ -171,6 +175,9 @@ fun UserAssetUrlScreen(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
.consumeWindowInsets(innerPadding)
.imePadding()
.verticalScroll(rememberScrollState())
.padding(vertical = 8.dp)
) {
FormTextField(