mirror of
https://github.com/BetterAndroid/FlexiUI.git
synced 2025-09-07 11:09:53 +08:00
feat: update demo
This commit is contained in:
@@ -21,18 +21,20 @@
|
||||
*/
|
||||
@file:OptIn(ExperimentalFoundationApi::class)
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@@ -41,34 +43,79 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.em
|
||||
import com.highcapable.betterandroid.compose.extension.ui.ComponentPadding
|
||||
import com.highcapable.betterandroid.compose.multiplatform.backpress.BackHandler
|
||||
import com.highcapable.betterandroid.compose.multiplatform.systembar.PlatformSystemBarStyle
|
||||
import com.highcapable.betterandroid.compose.multiplatform.systembar.rememberSystemBarsController
|
||||
import com.highcapable.betterandroid.compose.multiplatform.systembar.setStyle
|
||||
import com.highcapable.flexiui.FlexiTheme
|
||||
import com.highcapable.flexiui.component.AreaBox
|
||||
import com.highcapable.flexiui.component.AreaColumn
|
||||
import com.highcapable.flexiui.component.Button
|
||||
import com.highcapable.flexiui.component.DropdownList
|
||||
import com.highcapable.flexiui.component.DropdownMenuItem
|
||||
import com.highcapable.flexiui.component.HorizontalItemBox
|
||||
import com.highcapable.flexiui.component.Icon
|
||||
import com.highcapable.flexiui.component.IconDefaults
|
||||
import com.highcapable.flexiui.component.NavigationBarItem
|
||||
import com.highcapable.flexiui.component.NavigationBarRow
|
||||
import com.highcapable.flexiui.component.PrimaryAppBar
|
||||
import com.highcapable.flexiui.component.Scaffold
|
||||
import com.highcapable.flexiui.component.SecondaryAppBar
|
||||
import com.highcapable.flexiui.component.Surface
|
||||
import com.highcapable.flexiui.component.SwitchItem
|
||||
import com.highcapable.flexiui.component.Text
|
||||
import com.highcapable.flexiui.resources.FlexiIcons
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Stable
|
||||
data class AppPreferences(
|
||||
var darkMode: MutableState<Boolean> = mutableStateOf(false),
|
||||
var followSystemDarkMode: MutableState<Boolean> = mutableStateOf(false)
|
||||
)
|
||||
private const val PROJECT_URL = "https://github.com/BetterAndroid/FlexiUI"
|
||||
|
||||
@Composable
|
||||
private fun FlexiDemoTheme(content: @Composable () -> Unit) {
|
||||
val systemBars = rememberSystemBarsController()
|
||||
val darkMode by remember { Preferences.darkMode }
|
||||
val followSystemDarkMode by remember { Preferences.followSystemDarkMode }
|
||||
val currentDarkMode = if (followSystemDarkMode) isSystemInDarkTheme() else darkMode
|
||||
val colorScheme by remember { Preferences.colorScheme }
|
||||
systemBars.setStyle(
|
||||
if (currentDarkMode)
|
||||
PlatformSystemBarStyle.DarkTransparent
|
||||
else PlatformSystemBarStyle.LightTransparent
|
||||
)
|
||||
FlexiTheme(
|
||||
colors = colorScheme.toColors(currentDarkMode),
|
||||
content = content
|
||||
)
|
||||
}
|
||||
|
||||
/** Simulate a router. */
|
||||
@Stable
|
||||
private val Preferences = AppPreferences()
|
||||
private var CurrentPage = mutableStateOf(0)
|
||||
|
||||
@Composable
|
||||
private fun rememberCurrentPage() = remember { CurrentPage }
|
||||
|
||||
@Composable
|
||||
private fun Page(page: Int, content: @Composable () -> Unit) {
|
||||
val currentPage by remember { CurrentPage }
|
||||
AnimatedVisibility(
|
||||
visible = currentPage == page,
|
||||
enter = fadeIn(),
|
||||
exit = fadeOut()
|
||||
) { content() }
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun App() {
|
||||
FlexiTheme {
|
||||
MainScreen()
|
||||
FlexiDemoTheme {
|
||||
// Surface will keep the content background color when animation.
|
||||
Surface(padding = ComponentPadding()) {
|
||||
Page(0) { MainScreen() }
|
||||
Page(1) { SecondaryScreen() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,13 +124,14 @@ fun MainScreen() {
|
||||
val pageCount = 2
|
||||
val state = rememberPagerState(pageCount = { pageCount })
|
||||
val scope = rememberCoroutineScope()
|
||||
val uriHandler = LocalUriHandler.current
|
||||
Scaffold(
|
||||
appBar = {
|
||||
PrimaryAppBar(
|
||||
title = { Text("Flexi UI Demo") },
|
||||
actions = {
|
||||
ActionIconButton(
|
||||
onClick = { /* TODO */ }
|
||||
onClick = { uriHandler.openUri(PROJECT_URL) }
|
||||
) { Icon(FlexiIcons.GitHub) }
|
||||
}
|
||||
)
|
||||
@@ -127,24 +175,61 @@ fun MainHomePage() {
|
||||
}
|
||||
PrimarySpacer()
|
||||
AreaColumn(modifier = Modifier.fillMaxWidth()) {
|
||||
var colorScheme by remember { Preferences.colorScheme }
|
||||
var darkMode by remember { Preferences.darkMode }
|
||||
var followSystemDarkMode by remember { Preferences.followSystemDarkMode }
|
||||
SecondaryText("Theme Style")
|
||||
PrimarySpacer()
|
||||
SwitchItem(
|
||||
checked = darkMode,
|
||||
onCheckedChange = { darkMode = it }
|
||||
) { Text("Enable night mode") }
|
||||
SecondarySpacer()
|
||||
SecondaryText("Manually switch the current theme to night mode.")
|
||||
PrimarySpacer()
|
||||
AnimatedVisibility(visible = !followSystemDarkMode) {
|
||||
Column {
|
||||
SwitchItem(
|
||||
checked = darkMode,
|
||||
onCheckedChange = { darkMode = it }
|
||||
) { Text("Enable night mode") }
|
||||
SecondarySpacer()
|
||||
SecondaryText("Manually switch the current theme to night mode.")
|
||||
PrimarySpacer()
|
||||
}
|
||||
}
|
||||
SwitchItem(
|
||||
checked = followSystemDarkMode,
|
||||
onCheckedChange = { followSystemDarkMode = it }
|
||||
) { Text("Follow system night mode") }
|
||||
SecondarySpacer()
|
||||
SecondaryText("Follow the system theme to switch day and night mode.")
|
||||
PrimarySpacer()
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
Text("Current Theme")
|
||||
PrimarySpacer()
|
||||
DropdownList(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
expanded = expanded,
|
||||
onExpandedChange = { expanded = it },
|
||||
text = { Text(colorScheme.toName()) },
|
||||
) {
|
||||
colorSchemes().forEach {
|
||||
DropdownMenuItem(
|
||||
actived = colorScheme == it,
|
||||
onClick = {
|
||||
expanded = false
|
||||
colorScheme = it
|
||||
}
|
||||
) { Text(it.toName()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PrimarySpacer()
|
||||
var currentPage by rememberCurrentPage()
|
||||
HorizontalItemBox(
|
||||
onClick = { currentPage = 1 },
|
||||
title = { Text("Single Page Demo") },
|
||||
subtitle = { Text("Open a single page.") }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,20 +243,32 @@ fun MainComponentPage() {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PrimarySpacer() {
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SecondarySpacer() {
|
||||
Spacer(modifier = Modifier.height(5.dp))
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SecondaryText(text: String) {
|
||||
Text(
|
||||
text = text,
|
||||
color = FlexiTheme.colors.textSecondary,
|
||||
style = FlexiTheme.typography.secondary
|
||||
)
|
||||
fun SecondaryScreen() {
|
||||
var currentPage by rememberCurrentPage()
|
||||
Scaffold(
|
||||
appBar = {
|
||||
SecondaryAppBar(
|
||||
title = { Text("Single Page") },
|
||||
navigationIcon = {
|
||||
NavigationIconButton(onClick = { currentPage = 0 })
|
||||
}
|
||||
)
|
||||
}
|
||||
) {
|
||||
AreaColumn(modifier = Modifier.fillMaxWidth()) {
|
||||
Text(
|
||||
"""
|
||||
Now, you open a separate secondary page.
|
||||
You can click the button below to back to the homepage.
|
||||
""".trimIndent(),
|
||||
style = FlexiTheme.typography.primary.copy(lineHeight = 2.em)
|
||||
)
|
||||
PrimarySpacer()
|
||||
Button(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = { currentPage = 0 }
|
||||
) { Text("Take Me Home") }
|
||||
}
|
||||
BackHandler { currentPage = 0 }
|
||||
}
|
||||
}
|
50
samples/shared/src/commonMain/kotlin/Components.kt
Normal file
50
samples/shared/src/commonMain/kotlin/Components.kt
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Flexi UI - A flexible and useful UI component library.
|
||||
* Copyright (C) 2019-2024 HighCapable
|
||||
* https://github.com/BetterAndroid/FlexiUI
|
||||
*
|
||||
* Apache License Version 2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is created by fankes on 2024/1/11.
|
||||
*/
|
||||
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.highcapable.flexiui.FlexiTheme
|
||||
import com.highcapable.flexiui.component.Text
|
||||
|
||||
// TODO: Some components can be include to Flexi UI (To be determined)
|
||||
|
||||
@Composable
|
||||
fun PrimarySpacer() {
|
||||
Spacer(modifier = Modifier.size(10.dp))
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SecondarySpacer() {
|
||||
Spacer(modifier = Modifier.size(5.dp))
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SecondaryText(text: String) {
|
||||
Text(
|
||||
text = text,
|
||||
color = FlexiTheme.colors.textSecondary,
|
||||
style = FlexiTheme.typography.secondary
|
||||
)
|
||||
}
|
145
samples/shared/src/commonMain/kotlin/Preferences.kt
Normal file
145
samples/shared/src/commonMain/kotlin/Preferences.kt
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Flexi UI - A flexible and useful UI component library.
|
||||
* Copyright (C) 2019-2024 HighCapable
|
||||
* https://github.com/BetterAndroid/FlexiUI
|
||||
*
|
||||
* Apache License Version 2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is created by fankes on 2024/1/11.
|
||||
*/
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.highcapable.flexiui.blueColors
|
||||
import com.highcapable.flexiui.defaultColors
|
||||
import com.highcapable.flexiui.greenColors
|
||||
import com.highcapable.flexiui.isSystemColorAvailable
|
||||
import com.highcapable.flexiui.orangeColors
|
||||
import com.highcapable.flexiui.pinkColors
|
||||
import com.highcapable.flexiui.purpleColors
|
||||
import com.highcapable.flexiui.redColors
|
||||
import com.highcapable.flexiui.systemColors
|
||||
import com.highcapable.flexiui.yellowColors
|
||||
|
||||
@Stable
|
||||
data class AppPreferences(
|
||||
var colorScheme: MutableState<ColorScheme> = mutableStateOf(ColorScheme.Default),
|
||||
var darkMode: MutableState<Boolean> = mutableStateOf(false),
|
||||
var followSystemDarkMode: MutableState<Boolean> = mutableStateOf(false)
|
||||
)
|
||||
|
||||
// TODO: Include ColorScheme to Flexi UI's Colors.kt
|
||||
|
||||
@Stable
|
||||
val Preferences = AppPreferences()
|
||||
|
||||
@Stable
|
||||
enum class ColorScheme {
|
||||
Default,
|
||||
DefaultBlack,
|
||||
System,
|
||||
SystemBlack,
|
||||
Red,
|
||||
RedBlack,
|
||||
Pink,
|
||||
PinkBlack,
|
||||
Purple,
|
||||
PurpleBlack,
|
||||
Orange,
|
||||
OrangeBlack,
|
||||
Yellow,
|
||||
YellowBlack,
|
||||
Green,
|
||||
GreenBlack,
|
||||
Blue,
|
||||
BlueBlack
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun colorSchemes(): Array<ColorScheme> {
|
||||
val defaultColors = arrayOf(
|
||||
ColorScheme.Default,
|
||||
ColorScheme.DefaultBlack
|
||||
)
|
||||
val systemColors = arrayOf(
|
||||
ColorScheme.System,
|
||||
ColorScheme.SystemBlack
|
||||
)
|
||||
val presetColors = arrayOf(
|
||||
ColorScheme.Red,
|
||||
ColorScheme.RedBlack,
|
||||
ColorScheme.Pink,
|
||||
ColorScheme.PinkBlack,
|
||||
ColorScheme.Purple,
|
||||
ColorScheme.PurpleBlack,
|
||||
ColorScheme.Orange,
|
||||
ColorScheme.OrangeBlack,
|
||||
ColorScheme.Yellow,
|
||||
ColorScheme.YellowBlack,
|
||||
ColorScheme.Green,
|
||||
ColorScheme.GreenBlack,
|
||||
ColorScheme.Blue,
|
||||
ColorScheme.BlueBlack
|
||||
)
|
||||
return if (isSystemColorAvailable())
|
||||
defaultColors + systemColors + presetColors
|
||||
else defaultColors + presetColors
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ColorScheme.toColors(darkMode: Boolean) = when (this) {
|
||||
ColorScheme.Default -> defaultColors(darkMode)
|
||||
ColorScheme.DefaultBlack -> defaultColors(darkMode, blackDarkMode = true)
|
||||
ColorScheme.System -> systemColors(darkMode)
|
||||
ColorScheme.SystemBlack -> systemColors(darkMode, blackDarkMode = true)
|
||||
ColorScheme.Red -> redColors(darkMode)
|
||||
ColorScheme.RedBlack -> redColors(darkMode, blackDarkMode = true)
|
||||
ColorScheme.Pink -> pinkColors(darkMode)
|
||||
ColorScheme.PinkBlack -> pinkColors(darkMode, blackDarkMode = true)
|
||||
ColorScheme.Purple -> purpleColors(darkMode)
|
||||
ColorScheme.PurpleBlack -> purpleColors(darkMode, blackDarkMode = true)
|
||||
ColorScheme.Orange -> orangeColors(darkMode)
|
||||
ColorScheme.OrangeBlack -> orangeColors(darkMode, blackDarkMode = true)
|
||||
ColorScheme.Yellow -> yellowColors(darkMode)
|
||||
ColorScheme.YellowBlack -> yellowColors(darkMode, blackDarkMode = true)
|
||||
ColorScheme.Green -> greenColors(darkMode)
|
||||
ColorScheme.GreenBlack -> greenColors(darkMode, blackDarkMode = true)
|
||||
ColorScheme.Blue -> blueColors(darkMode)
|
||||
ColorScheme.BlueBlack -> blueColors(darkMode, blackDarkMode = true)
|
||||
}
|
||||
|
||||
@Stable
|
||||
fun ColorScheme.toName() = when (this) {
|
||||
ColorScheme.Default -> "Default"
|
||||
ColorScheme.DefaultBlack -> "Default (Black)"
|
||||
ColorScheme.System -> "System"
|
||||
ColorScheme.SystemBlack -> "System (Black)"
|
||||
ColorScheme.Red -> "Red"
|
||||
ColorScheme.RedBlack -> "Red (Black)"
|
||||
ColorScheme.Pink -> "Pink"
|
||||
ColorScheme.PinkBlack -> "Pink (Black)"
|
||||
ColorScheme.Purple -> "Purple"
|
||||
ColorScheme.PurpleBlack -> "Purple (Black)"
|
||||
ColorScheme.Orange -> "Orange"
|
||||
ColorScheme.OrangeBlack -> "Orange (Black)"
|
||||
ColorScheme.Yellow -> "Yellow"
|
||||
ColorScheme.YellowBlack -> "Yellow (Black)"
|
||||
ColorScheme.Green -> "Green"
|
||||
ColorScheme.GreenBlack -> "Green (Black)"
|
||||
ColorScheme.Blue -> "Blue"
|
||||
ColorScheme.BlueBlack -> "Blue (Black)"
|
||||
}
|
Reference in New Issue
Block a user