Update android studio. Add compose settings screen.
Some checks are pending
continuous-integration/drone/push Build is pending

This commit is contained in:
2023-01-19 19:38:01 +01:00
parent bcc08e4605
commit e09bd26859
16 changed files with 245 additions and 107 deletions

View File

@@ -30,7 +30,7 @@ android {
targetSdkVersion 33
versionCode versionProperties["versionCode"].toInteger()
versionName "1.1.0Beta1"
resConfigs("de", "en")
resConfigs 'de', 'en'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
vectorDrawables {

View File

@@ -7,17 +7,23 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.os.LocaleListCompat
import androidx.preference.PreferenceManager
import dagger.hilt.android.AndroidEntryPoint
import me.zobrist.tichucounter.domain.Language
import me.zobrist.tichucounter.domain.SettingsAdapter
import me.zobrist.tichucounter.domain.Theme
import javax.inject.Inject
@AndroidEntryPoint
abstract class BaseActivity : AppCompatActivity(),
SharedPreferences.OnSharedPreferenceChangeListener {
@Inject
lateinit var settingsAdapter: SettingsAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
keepScreenOn(sharedPreferences.getBoolean("screen_on", false))
updateTheme(sharedPreferences.getString("theme", null))
keepScreenOn(settingsAdapter.keepScreenOn)
updateTheme(settingsAdapter.theme)
PreferenceManager.getDefaultSharedPreferences(this)
.registerOnSharedPreferenceChangeListener(this)
@@ -37,20 +43,19 @@ abstract class BaseActivity : AppCompatActivity(),
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String?) {
when (key) {
"language" -> setLanguage(sharedPreferences.getString(key, null))
"screen_on" -> keepScreenOn(sharedPreferences.getBoolean(key, false))
"theme" -> updateTheme(sharedPreferences.getString(key, null))
settingsAdapter.language::class.simpleName -> setLanguage(settingsAdapter.language)
settingsAdapter.keepScreenOn::class.simpleName -> keepScreenOn(settingsAdapter.keepScreenOn)
settingsAdapter.theme::class.simpleName -> updateTheme(settingsAdapter.theme)
}
}
private fun updateTheme(theme: String?) {
private fun updateTheme(theme: Theme) {
val themeValue = when (theme) {
"light" -> AppCompatDelegate.MODE_NIGHT_NO
"dark" -> AppCompatDelegate.MODE_NIGHT_YES
"default" -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
Theme.LIGHT -> AppCompatDelegate.MODE_NIGHT_NO
Theme.DARK -> AppCompatDelegate.MODE_NIGHT_YES
Theme.DEFAULT -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
}
if (themeValue != AppCompatDelegate.getDefaultNightMode()) {
@@ -67,7 +72,13 @@ abstract class BaseActivity : AppCompatActivity(),
}
}
private fun setLanguage(locale: String?) {
private fun setLanguage(language: Language) {
val locale = when (language) {
Language.ENGLISH -> "en"
Language.GERMAN -> "de"
else -> null
}
val currentLocale = AppCompatDelegate.getApplicationLocales()[0].toString()

View File

@@ -31,6 +31,8 @@ import me.zobrist.tichucounter.ui.MainViewModel
import me.zobrist.tichucounter.ui.counter.*
import me.zobrist.tichucounter.ui.history.HistoryList
import me.zobrist.tichucounter.ui.history.HistoryViewModel
import me.zobrist.tichucounter.ui.settings.SettingsView
import me.zobrist.tichucounter.ui.settings.SettingsViewModel
import javax.inject.Inject
@AndroidEntryPoint
@@ -41,6 +43,7 @@ class MainActivity : BaseActivity() {
private val counterViewModel: CounterViewModel by viewModels()
private val historyViewModel: HistoryViewModel by viewModels()
private val settingsViewModel: SettingsViewModel by viewModels()
private val mainViewModel: MainViewModel by viewModels()
@@ -79,9 +82,7 @@ class MainActivity : BaseActivity() {
}
composable("settings") {
Column() {
Text("Settings")
}
SettingsView(settingsViewModel)
mainViewModel.setActions(emptyList())
}
}

View File

@@ -0,0 +1,50 @@
package me.zobrist.tichucounter.domain
import android.content.Context
import androidx.preference.PreferenceManager
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
enum class Theme { DEFAULT, DARK, LIGHT }
enum class Language { DEFAULT, GERMAN, ENGLISH }
class SettingsAdapter @Inject constructor(@ApplicationContext private val context: Context) {
private val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
val language: Language
get() {
return Language.values()[sharedPreferences.getInt(Language::class.simpleName, 0)]
}
val theme: Theme
get() {
return Theme.values()[sharedPreferences.getInt(Theme::class.simpleName, 0)]
}
val keepScreenOn: Boolean
get() {
return sharedPreferences.getBoolean("keep_screen_on", false)
}
fun setLanguage(language: Language) {
val editor = sharedPreferences.edit()
editor.putInt(Language::class.simpleName, language.ordinal)
editor.commit()
}
fun setTheme(theme: Theme) {
val editor = sharedPreferences.edit()
editor.putInt(Theme::class.simpleName, theme.ordinal)
editor.commit()
}
fun setKeepScreenOn(setting: Boolean) {
val editor = sharedPreferences.edit()
editor.putBoolean("keep_screen_on", setting)
editor.commit()
}
}

View File

@@ -0,0 +1,122 @@
package me.zobrist.tichucounter.ui.settings
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Check
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import me.zobrist.tichucounter.R
import me.zobrist.tichucounter.domain.Language
import me.zobrist.tichucounter.domain.Theme
val languageMap = mapOf(
Language.DEFAULT to R.string.android_default_text,
Language.ENGLISH to R.string.english,
Language.GERMAN to R.string.german
)
val themeMap = mapOf(
Theme.DEFAULT to R.string.android_default_text,
Theme.DARK to R.string.dark,
Theme.LIGHT to R.string.light
)
@Composable
fun SettingsView(viewModel: SettingsViewModel) {
SettingsView(
viewModel.screenOn,
viewModel.language,
viewModel.theme,
{ viewModel.updateScreenOn(it) },
{ viewModel.updateLanguage(it) },
{ viewModel.updateTheme(it) })
}
@Preview
@Composable
fun SettingsView(
valueScreenOn: Boolean = true,
valueLanguage: Language = Language.ENGLISH,
valueTheme: Theme = Theme.DARK,
updateScreenOn: (Boolean) -> Unit = {},
updateLanguage: (Language) -> Unit = {},
updateTheme: (Theme) -> Unit = {}
) {
Column() {
BooleanSetting(
stringResource(R.string.keep_screen_on),
valueScreenOn
) { updateScreenOn(it) }
StringSetting(
stringResource(R.string.choose_language_text),
languageMap,
valueLanguage,
) { updateLanguage(it) }
StringSetting(
stringResource(R.string.choose_theme_text),
themeMap,
valueTheme,
) { updateTheme(it) }
}
}
@Composable
fun BooleanSetting(name: String, value: Boolean, updateValue: (Boolean) -> Unit) {
Row {
Column() {
Text(text = name)
}
Column() {
Checkbox(checked = value, onCheckedChange = { updateValue(it) })
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun <T> StringSetting(name: String, map: Map<T, Int>, selected: T, onSelected: (T) -> Unit) {
var expanded by remember { mutableStateOf(false) }
Row() {
TextField(
value = stringResource(map[selected]!!),
onValueChange = { },
singleLine = true,
label = { Text(name) },
readOnly = true,
modifier = Modifier
.onFocusChanged {
if (it.isFocused) {
expanded = true
}
}
)
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
map.forEach {
DropdownMenuItem(
onClick = {
onSelected(it.key)
expanded = false
},
text = { Text(stringResource(it.value)) },
trailingIcon = {
if (it.key == selected) {
Icon(Icons.Outlined.Check, contentDescription = null)
}
})
}
}
}
}

View File

@@ -0,0 +1,41 @@
package me.zobrist.tichucounter.ui.settings
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import me.zobrist.tichucounter.domain.Language
import me.zobrist.tichucounter.domain.SettingsAdapter
import me.zobrist.tichucounter.domain.Theme
import javax.inject.Inject
@HiltViewModel
class SettingsViewModel @Inject constructor(private val settings: SettingsAdapter) : ViewModel() {
var language by mutableStateOf(settings.language)
private set
var theme by mutableStateOf(settings.theme)
private set
var screenOn by mutableStateOf(false)
private set
fun updateLanguage(language: Language) {
settings.setLanguage(language)
this.language = settings.language
}
fun updateTheme(theme: Theme) {
settings.setTheme(theme)
this.theme = settings.theme
}
fun updateScreenOn(value: Boolean) {
settings.setKeepScreenOn(value)
screenOn = settings.keepScreenOn
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:showIn="navigation_view">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_counter"
android:icon="@drawable/ic_menu_camera"
android:title="@string/menu_counter" />
<item
android:id="@+id/nav_history"
android:icon="@drawable/ic_menu_gallery"
android:title="@string/menu_history" />
<item
android:id="@+id/nav_settings"
android:icon="@drawable/ic_menu_slideshow"
android:title="@string/menu_settings" />
</group>
</menu>

View File

@@ -1,18 +0,0 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="me.zobrist.tichucounter.MainActivity">
<item
android:id="@+id/action_undo"
android:icon="@drawable/ic_baseline_undo_24"
android:orderInCategory="5"
android:title="@string/undo"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_new"
android:checkable="false"
android:icon="@drawable/ic_baseline_add_24"
android:orderInCategory="10"
android:title="@string/clear"
app:showAsAction="ifRoom" />
</menu>

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@+id/nav_counter">
<fragment
android:id="@+id/nav_counter"
android:name="me.zobrist.tichucounter.ui.counter.CounterFragment"
android:label="@string/menu_counter"
tools:layout="@layout/fragment_counter" />
<fragment
android:id="@+id/nav_history"
android:name="me.zobrist.tichucounter.ui.history.HistoryFragment"
android:label="@string/menu_history"
tools:layout="@layout/fragment_slideshow" />
<fragment
android:id="@+id/nav_settings"
android:name="me.zobrist.tichucounter.ui.settings.SettingsFragment"
android:label="@string/menu_settings" />
</navigation>

View File

@@ -1,25 +0,0 @@
<resources>
<!-- Theme Preference -->
<string-array name="theme_entries">
<item>@string/dark</item>
<item>@string/light</item>
<item>@string/android_default_text</item>
</string-array>
<string-array name="theme_values">
<item>dark</item>
<item>light</item>
<item>default</item>
</string-array>
<!-- Language Preference -->
<string-array name="language_entries">
<item>@string/english</item>
<item>@string/german</item>
</string-array>
<string-array name="language_values">
<item>en</item>
<item>de</item>
</string-array>
</resources>