feat(v1.8.0): IMPL_01 Language Settings - Smooth Language Switching
- Prevent activity recreate during language changes via configChanges - Add onConfigurationChanged() handler in ComposeSettingsActivity - Simplify setAppLanguage() - let system handle locale change smoothly - Update language_info strings to reflect smooth transition - Remove unused Activity parameter and imports Fixes flicker during language switching by handling configuration changes instead of recreating the entire activity. Compose recomposes automatically when locale changes, providing seamless UX.
This commit is contained in:
@@ -69,8 +69,10 @@
|
||||
android:parentActivityName=".ui.main.ComposeMainActivity" />
|
||||
|
||||
<!-- Settings Activity v1.5.0 (Jetpack Compose) -->
|
||||
<!-- v1.8.0: Handle locale changes without recreate for smooth language switching -->
|
||||
<activity
|
||||
android:name=".ui.settings.ComposeSettingsActivity"
|
||||
android:configChanges="locale|layoutDirection"
|
||||
android:parentActivityName=".ui.main.ComposeMainActivity"
|
||||
android:theme="@style/Theme.SimpleNotes" />
|
||||
|
||||
|
||||
@@ -189,4 +189,16 @@ class ComposeSettingsActivity : AppCompatActivity() {
|
||||
Logger.e(TAG, "❌ Failed to restart NetworkMonitor: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle configuration changes (e.g., locale) without recreating activity
|
||||
* v1.8.0: Prevents flickering during language changes by avoiding full recreate
|
||||
* Compose automatically recomposes when configuration changes
|
||||
*/
|
||||
override fun onConfigurationChanged(newConfig: android.content.res.Configuration) {
|
||||
super.onConfigurationChanged(newConfig)
|
||||
Logger.d(TAG, "📱 Configuration changed (likely locale switch) - Compose will recompose")
|
||||
// Compose handles UI updates automatically via recomposition
|
||||
// No manual action needed - stringResource() etc. will pick up new locale
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package dev.dettmer.simplenotes.ui.settings.screens
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
@@ -15,7 +14,6 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.os.LocaleListCompat
|
||||
@@ -35,8 +33,6 @@ import dev.dettmer.simplenotes.ui.settings.components.SettingsScaffold
|
||||
fun LanguageSettingsScreen(
|
||||
onBack: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
||||
// Get current app locale - fresh value each time (no remember, always reads current state)
|
||||
val currentLocale = AppCompatDelegate.getApplicationLocales()
|
||||
val currentLanguageCode = if (currentLocale.isEmpty) {
|
||||
@@ -92,7 +88,7 @@ fun LanguageSettingsScreen(
|
||||
onValueSelected = { newLanguage ->
|
||||
if (newLanguage != selectedLanguage) {
|
||||
selectedLanguage = newLanguage
|
||||
setAppLanguage(newLanguage, context as Activity)
|
||||
setAppLanguage(newLanguage)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -102,19 +98,19 @@ fun LanguageSettingsScreen(
|
||||
|
||||
/**
|
||||
* Set app language using AppCompatDelegate
|
||||
* Works on Android 13+ natively, falls back to AppCompat on older versions
|
||||
* v1.8.0: Smooth language change without activity recreate
|
||||
*
|
||||
* ComposeSettingsActivity handles locale changes via android:configChanges="locale"
|
||||
* in AndroidManifest.xml, preventing full activity recreate and eliminating flicker.
|
||||
* Compose automatically recomposes when the configuration changes.
|
||||
*/
|
||||
private fun setAppLanguage(languageCode: String, activity: Activity) {
|
||||
private fun setAppLanguage(languageCode: String) {
|
||||
val localeList = if (languageCode.isEmpty()) {
|
||||
LocaleListCompat.getEmptyLocaleList()
|
||||
} else {
|
||||
LocaleListCompat.forLanguageTags(languageCode)
|
||||
}
|
||||
|
||||
// Sets the app locale - triggers onConfigurationChanged() instead of recreate()
|
||||
AppCompatDelegate.setApplicationLocales(localeList)
|
||||
|
||||
// Restart the activity to apply the change
|
||||
// On Android 13+ the system handles this automatically for some apps,
|
||||
// but we need to recreate to ensure our Compose UI recomposes with new locale
|
||||
activity.recreate()
|
||||
}
|
||||
|
||||
@@ -409,7 +409,7 @@
|
||||
<string name="language_system_default">Systemstandard</string>
|
||||
<string name="language_english">English</string>
|
||||
<string name="language_german">Deutsch</string>
|
||||
<string name="language_info">ℹ️ Wähle deine bevorzugte Sprache. Die App wird neu gestartet, um die Änderung anzuwenden.</string>
|
||||
<string name="language_info">ℹ️ Wähle deine bevorzugte Sprache. Die Ansicht wird kurz aktualisiert, um die Änderung anzuwenden.</string>
|
||||
<string name="language_changed_restart">Sprache geändert. Neustart…</string>
|
||||
|
||||
<!-- ============================= -->
|
||||
|
||||
@@ -409,7 +409,7 @@
|
||||
<string name="language_system_default">System Default</string>
|
||||
<string name="language_english">English</string>
|
||||
<string name="language_german">Deutsch</string>
|
||||
<string name="language_info">ℹ️ Choose your preferred language. The app will restart to apply the change.</string>
|
||||
<string name="language_info">ℹ️ Choose your preferred language. The view will briefly refresh to apply the change.</string>
|
||||
<string name="language_changed_restart">Language changed. Restarting…</string>
|
||||
|
||||
<!-- ============================= -->
|
||||
|
||||
Reference in New Issue
Block a user