feat: update demo

This commit is contained in:
2024-01-11 23:12:46 +08:00
parent 5616bb29e2
commit c213f5d507
3 changed files with 327 additions and 35 deletions

View File

@@ -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 }
}
}

View 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
)
}

View 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)"
}