欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

利用Jetpack Compose實(shí)現(xiàn)主題切換功能

 更新時(shí)間:2022年01月27日 10:33:11   作者:九狼  
這篇文章主要介紹了如何利用Android中的Jetpack Compose實(shí)現(xiàn)主題切換功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)有一定幫助,需要的可以參考一下

前言

新建的Compose項(xiàng)目默認(rèn)的 Material 主題為我們提供了一些顏色,但對(duì)我這種花里胡哨的人來說根本不夠呀。 所以系統(tǒng)提供的主題不能滿足需求時(shí)候可以自己配置主題

compose 實(shí)現(xiàn)換膚很簡(jiǎn)單

之前xml方法可復(fù)雜了

通過LayoutInflater調(diào)用inflate方法加載XML布局,在inflate方法中有一個(gè)createViewFromTag,再根據(jù)LayoutInflater當(dāng)中Factory的接口類型(Factory or Factory2)調(diào)用CreateView方法加載,其中通過“name”可以得到加載的控件Tag,再通過AttributeSet得到控件的全部屬性最后再切換背景顏色

這是默認(rèn)的代碼,我們要改造一下

color.kt

先是用全局靜態(tài)變量寫一套顏色變量

val statusBarColorLight = Color(0xFFFFFFFF)
val statusBarColorDark = Color(0xFF1C1C28)

val backgroundColorLight = Color(0xFFF2F2F6)
val backgroundColorDark = Color(0xFF1C1C28)

val textPrimaryLight = Color(0xFF333333)
val textPrimaryDark = Color(0xFFE8E8F0)

val textSecondaryLight = Color(0xFF999999)
val textSecondaryDark = Color(0xFF999999)

...此處省略500字 哈哈

Theme.kt

定義各種各樣的顏色名稱

@Stable
class AppColors(
    statusBarColor: Color,
    themeUi: Color,
    background: Color,
    listItem: Color,
    divider: Color,
    textPrimary: Color,
    textSecondary: Color,
    mainColor: Color,
    card: Color,
    icon: Color,
    info: Color,
    warn: Color,
    success: Color,
    error: Color,
    primaryBtnBg: Color,
    secondBtnBg: Color,
    hot: Color,
    placeholder: Color,
)

接著引入mutableStateOf,來標(biāo)明這個(gè)Color是有狀態(tài)的,如果狀態(tài)發(fā)生了改變,所有引用這個(gè)顏色的控件都發(fā)生了改變,都需要重新繪制!

var statusBarColor: Color by mutableStateOf(statusBarColor)
    internal set
var themeUi: Color by mutableStateOf(themeUi)
    internal set
var background: Color by mutableStateOf(background)
    private set
var listItem: Color by mutableStateOf(listItem)
    private set
var divider: Color by mutableStateOf(divider)
    private set
var textPrimary: Color by mutableStateOf(textPrimary)
    internal set
var textSecondary: Color by mutableStateOf(textSecondary)
    private set
var mainColor: Color by mutableStateOf(mainColor)
    internal set
var card: Color by mutableStateOf(card)
    private set
var icon: Color by mutableStateOf(icon)
    private set
var info: Color by mutableStateOf(info)
    private set
var warn: Color by mutableStateOf(warn)
    private set
var success: Color by mutableStateOf(success)
    private set
var error: Color by mutableStateOf(error)
    private set
var primaryBtnBg: Color by mutableStateOf(primaryBtnBg)
    internal set
var secondBtnBg: Color by mutableStateOf(secondBtnBg)
    private set
var hot: Color by mutableStateOf(hot)
    private set
var placeholder: Color by mutableStateOf(placeholder)
    private set

復(fù)制粘貼就行啦

接著定義兩套主題 白天和黑夜

你永遠(yuǎn)不懂我傷悲

像白天不懂夜的黑

//夜色主題
private val DarkColorPalette = AppColors(
    statusBarColor = statusBarColorDark,
    themeUi = themeColor,
    background = backgroundColorDark,
    listItem = listItemDark,
    divider = dividerDark,
    textPrimary = textPrimaryDark,
    textSecondary = textSecondaryDark,
    mainColor = black3,
    card = black3,
    icon = grey1,
    info = info,
    warn = warn,
    success = green3,
    error = red2,
    primaryBtnBg = backgroundColorDark,
    secondBtnBg = black3,
    hot = red,
    placeholder = grey1,
)

//白天主題
private val LightColorPalette = AppColors(
    statusBarColor = statusBarColorLight,
    themeUi = themeColor,
    background = backgroundColorLight,
    listItem = listItemLight,
    divider = dividerLight,
    textPrimary = textPrimaryLight,
    textSecondary = textSecondaryLight,
    mainColor = white,
    card = white1,
    icon = inonGary,
    info = info,
    warn = warn,
    success = green3,
    error = red2,
    primaryBtnBg = themeColor,
    secondBtnBg = white3,
    hot = red,
    placeholder = white3,
)

接著重要的一步來了,如何應(yīng)用這些顏色配色呢?

@Composable
fun AppTheme(
    content: @Composable () -> Unit
)

就是這樣

只需要在使用的時(shí)候把控件裝在里面就行了

應(yīng)用之前我們要判斷使用哪個(gè)主題

這里我用深色模式來演示

在Composable下可以用這行代碼判斷當(dāng)前系統(tǒng)處于深色模式

isSystemInDarkTheme()
var LocalAppColors = compositionLocalOf {
    LightColorPalette
}
//主題配置單例
@Stable
object CustomTheme {
    val colors: AppColors
        @Composable
        get() = LocalAppColors.current

  //創(chuàng)建主題枚舉
    enum class Theme {
        Light, Dark
    }
}

關(guān)于compositionLocalOf

官方解釋如下: Compose 將數(shù)據(jù)通過組合樹顯式地通過參數(shù)傳遞給可組合函數(shù)。這通常是讓數(shù)據(jù)流過樹的最簡(jiǎn)單和最好的方法。

有時(shí),對(duì)于許多組件需要的數(shù)據(jù),或者當(dāng)組件需要在彼此之間傳遞數(shù)據(jù)但保持該實(shí)現(xiàn)細(xì)節(jié)私有時(shí),此模型可能很麻煩或分解。對(duì)于這些情況,CompositionLocal 可以用作讓數(shù)據(jù)流過組合的隱式方式。

CompositionLocal本質(zhì)上是分層的。當(dāng)CompositionLocal需要將的值限定為組合的特定子層次結(jié)構(gòu)時(shí),它們是有意義的。

必須創(chuàng)建一個(gè)CompositionLocal實(shí)例,該實(shí)例可以被消費(fèi)者靜態(tài)引用。CompositionLocal實(shí)例本身不持有任何數(shù)據(jù),可以將其視為傳遞到樹中的數(shù)據(jù)的類型安全標(biāo)識(shí)符。CompositionLocal工廠函數(shù)采用單個(gè)參數(shù):在CompositionLocal沒有提供程序的情況下使用a 的情況下創(chuàng)建默認(rèn)值的工廠。如果這是您不想處理的情況,則可以在此工廠中引發(fā)錯(cuò)誤。

在樹上的某個(gè)地方,CompositionLocalProvider可以使用一個(gè)組件,它為CompositionLocal. 這通常位于樹的“根”,但也可以在任何地方,也可以在多個(gè)位置使用以覆蓋子樹的提供值。 中間組件不需要知道該CompositionLocal值,并且可以對(duì)其具有零依賴關(guān)系

完整代碼

@Composable
fun AppTheme(
    isDark :Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {

    val targetColors = if (isDark) DarkColorPalette else LightColorPalette

    val statusBarColor = animateColorAsState(targetColors.statusBarColor, TweenSpec(600))
    val themeUi = animateColorAsState(targetColors.themeUi, TweenSpec(600))
    val background = animateColorAsState(targetColors.background, TweenSpec(600))
    val listItem = animateColorAsState(targetColors.listItem, TweenSpec(600))
    val divider = animateColorAsState(targetColors.divider, TweenSpec(600))
    val textPrimary = animateColorAsState(targetColors.textPrimary, TweenSpec(600))
    val textSecondary = animateColorAsState(targetColors.textSecondary, TweenSpec(600))
    val mainColor = animateColorAsState(targetColors.mainColor, TweenSpec(600))
    val card = animateColorAsState(targetColors.card, TweenSpec(600))
    val icon = animateColorAsState(targetColors.icon, TweenSpec(600))
    val info = animateColorAsState(targetColors.info, TweenSpec(600))
    val warn = animateColorAsState(targetColors.warn, TweenSpec(600))
    val success = animateColorAsState(targetColors.success, TweenSpec(600))
    val error = animateColorAsState(targetColors.error, TweenSpec(600))
    val primaryBtnBg = animateColorAsState(targetColors.primaryBtnBg, TweenSpec(600))
    val secondBtnBg = animateColorAsState(targetColors.secondBtnBg, TweenSpec(600))
    val hot = animateColorAsState(targetColors.hot, TweenSpec(600))
    val placeholder = animateColorAsState(targetColors.placeholder, TweenSpec(600))

    val appColors = AppColors(
        statusBarColor = statusBarColor.value,
        themeUi = themeUi.value,
        background = background.value,
        listItem = listItem.value,
        divider = divider.value,
        textPrimary = textPrimary.value,
        textSecondary = textSecondary.value,
        mainColor = mainColor.value,
        card = card.value,
        icon = icon.value,
        primaryBtnBg = primaryBtnBg.value,
        secondBtnBg = secondBtnBg.value,
        info = info.value,
        warn = warn.value,
        success = success.value,
        error = error.value,
        hot = hot.value,
        placeholder = placeholder.value
    )

    ProvideWindowInsets {
        CompositionLocalProvider(LocalAppColors provides appColors) {
            MaterialTheme(
                shapes = shapes
            ) {
                ProvideWindowInsets(content = content)
            }
        }
    }
}

用TweenSpec創(chuàng)建配置了給定持續(xù)時(shí)間、延遲和緩和曲線的效果 反正就是可以在換膚的時(shí)候不會(huì)一閃,會(huì)慢慢切換

最后放在AppTheme下面使用就可以啦

到此這篇關(guān)于利用Jetpack Compose實(shí)現(xiàn)主題切換功能的文章就介紹到這了,更多相關(guān)Jetpack Compose內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論