[Android]Jetpack Compose自定义主题

1.ColorScheme

ColorScheme 是 Jetpack Compose 中的一个类,用于定义一组颜色,这些颜色共同构成了应用程序的颜色主题。在 Material Design 系统中,颜色方案帮助确保应用程序具有一致的视觉外观,同时也支持色彩的可访问性和美观性。

(1).作用

  • 一致性ColorScheme 提供了一套标准化的颜色定义,这些颜色在整个应用的不同组件和界面之间使用,从而保持视觉一致性。

  • 美观性:通过精心选择的颜色组合,ColorScheme 能够提高应用的整体美观性。

  • 可访问性:通过为不同的视觉元素(如前景和背景)提供足够对比的颜色,ColorScheme 增强了内容的可读性,使应用更易于使用,尤其是视觉障碍用户。

  • 主题切换:支持明暗模式切换或其他主题变体时,ColorScheme 可以轻松调整以适应不同的环境需求。

(2).包含的颜色

ColorScheme提供了如下这些方案

class ColorScheme(/* 主色系 */primary: Color, // 主色,用于应用的大部分 UI 元素,如按钮、选中的选项卡等。onPrimary: Color, // 在主色上清晰显示的颜色,通常用于文本或图标。primaryContainer: Color, // 主色的容器色,用于需要主色变体的元素背景。onPrimaryContainer: Color, // 在主色容器上清晰显示的颜色,通常用于文本或图标。inversePrimary: Color, // 主色的反色,用于在对比背景上需要主色时。/* 次色系 */secondary: Color, // 次级色,用于补充主色或用作次要的 UI 元素。onSecondary: Color, // 在次级色上清晰显示的颜色,通常用于文本或图标。secondaryContainer: Color, // 次级色的容器色,用于需要次级色变体的元素背景。onSecondaryContainer: Color, // 在次级色容器上清晰显示的颜色,通常用于文本或图标。/* 第三色系 */tertiary: Color, // 第三色,用于需要注意或区分的 UI 元素。onTertiary: Color, // 在第三色上清晰显示的颜色,通常用于文本或图标。tertiaryContainer: Color, // 第三色的容器色,用于背景或填充色。onTertiaryContainer: Color, // 在第三色容器上清晰显示的颜色,通常用于文本或图标。/* 背景与表面色 */background: Color, // 背景色,用于页面或组件的背景。onBackground: Color, // 在背景色上清晰显示的颜色,通常用于文本或图标。surface: Color, // 表面色,用于卡片、菜单和其他元素的背景。onSurface: Color, // 在表面色上清晰显示的颜色,通常用于文本或图标。surfaceVariant: Color, // 表面色的变体,用于需要区分的表面元素。onSurfaceVariant: Color, // 在表面色变体上清晰显示的颜色。surfaceTint: Color, // 表面色的着色,通常用于表面元素的图标或小组件。inverseSurface: Color, // 表面色的反色,用于需要高对比度的背景。inverseOnSurface: Color, // 在反表面色上清晰显示的颜色。/* 错误处理色 */error: Color, // 错误色,用于指示错误或警告状态,如输入校验失败。onError: Color, // 在错误色上清晰显示的颜色,通常用于错误文本或图标。errorContainer: Color, // 错误色的容器色,用于错误状态的背景。onErrorContainer: Color, // 在错误容器色上清晰显示的颜色。/* 其他 */outline: Color, // 用于元素边框的颜色。outlineVariant: Color, // 边框颜色的变体,可能用于更细微的分界线。scrim: Color, // 遮罩层颜色,通常用于遮盖或暗化背景中的内容。
) {...
}

(3).使用示例

在 Jetpack Compose 中,你可以使用 MaterialTheme 来应用 ColorScheme,如下所示:

@Composable
fun MyAppTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {val colors = if (darkTheme) {darkColorScheme(primary = Color.Blue,secondary = Color.Green,background = Color.Black)} else {lightColorScheme(primary = Color.Blue,secondary = Color.Green,background = Color.White)}MaterialTheme(colorScheme = colors,typography = Typography,content = content)
}

2.颜色管理(ui.theme/Color.kt)

在Color.kt管理颜色

package com.randomdt.www.ui.themeimport androidx.compose.ui.graphics.Color
// 主题色 
val theme_color = Color(0xFF9279F8)
// 主要背景色
val theme_background_color = Color(0xFF161517)// 文字主色 
val text_color = Color(0xFFFFFFFF)
// 文字辅色
val text_aux33 = Color(0xFF333333)
val text_aux66 = Color(0xFF666666)
val text_aux99 = Color(0xFF999999)

也可以想以前一样, 在colors.xml中管理颜色

<?xml version="1.0" encoding="utf-8"?>
<resources><!-- 主题色 --><color name="theme_color">#9279F8</color><!-- 主要背景色 --><color name="theme_background_color">#161517</color><!-- 文字主色 --><color name="text_color">#FFFFFF</color><!-- 文字辅色 --><color name="text_aux33">#333333</color><color name="text_aux66">#666666</color><color name="text_aux99">#999999</color></resources>
@Composable
fun darkCustomTheme() = CustomThemeData (textColor = colorResource(id = R.color.text_aux33)
)

3.重设深色/浅色模式的主题颜色(ui.theme/Theme.kt)

如果需要更改ColorScheme对应的颜色值, 只需要在定义主题中对具体颜色重写赋值即可.

@Composable
fun reDarkColorScheme(): ColorScheme = darkColorScheme(primary = theme_color,background = theme_background_color
)@Composable
fun reLightColorScheme(): ColorScheme = lightColorScheme(primary = theme_color,background = theme_background_color
)@Composable
fun RandomdtTheme(darkTheme: Boolean = isSystemInDarkTheme(),// Dynamic color is available on Android 12+dynamicColor: Boolean = false,  // 禁用动态颜色, 这样无论设备运行的Android版本如何,都会使用你定义的颜色方案. 启用了动态颜色时, 会在 Android 12+ 上覆盖自定义颜色方案。content: @Composable () -> Unit
) {val colorScheme = when {dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {val context = LocalContext.currentif (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)}darkTheme -> reDarkColorScheme()else -> reLightColorScheme()}MaterialTheme(colorScheme = colorScheme,typography = Typography,content = content())}

使用示例:

组件中的获取颜色从,使用MaterialTheme.colorScheme.xxx这种方式.

class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {RandomdtTheme {// A surface container using the 'background' color from the themeSurface(modifier = Modifier.fillMaxSize(),color = MaterialTheme.colorScheme.background// color = theme_background_color // 也可以直接从颜色管理获取颜色// color = colorResource(id = R.color.theme_background_color) // 以前从Color.xml获取颜色) {Greeting("Android")}}}}
}

3.自定义主题

ColorScheme中的颜色名称是固定的, 如果你想在其中添加一个名称为“textColor”的颜色, 就办不到. 

这里, 我们定义成使用MaterialTheme.customScheme.xxx的方式获取属性. 

data class CustomThemeData(// 定义颜色val textColor: androidx.compose.ui.graphics.Color,// 定义形状// 定义字体...
)@Composable
fun darkCustomTheme() = CustomThemeData (textColor = text_aux33
)
@Composable
fun lightCustomTheme() = CustomThemeData (textColor = text_aux99
)
val CustomThemes = compositionLocalOf<CustomThemeData> { error("No Color provided") }val MaterialTheme.customScheme: CustomThemeData@Composable@ReadOnlyComposableget() = CustomThemes.current@Composable
fun RandomdtTheme(darkTheme: Boolean = isSystemInDarkTheme(),// Dynamic color is available on Android 12+dynamicColor: Boolean = false,  content: @Composable () -> Unit
) {......CompositionLocalProvider(CustomThemes provides if (darkTheme) darkCustomTheme() else lightCustomTheme()) {MaterialTheme(colorScheme = colorScheme,typography = Typography,content = content())}
}

使用示例:

MyTheme {Text(text = "Hello Android!",color = MaterialTheme.customScheme.textColor,)
)

4.完整代码示例

package com.randomdt.www.ui.themeimport android.app.Activity
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.core.view.WindowCompat
import com.randomdt.www.support.tools.findActivity/** 修改主题中颜色 */
@Composable
fun reDarkColorScheme(): ColorScheme = darkColorScheme(primary = theme_color,background = theme_background_color
)@Composable
fun reLightColorScheme(): ColorScheme = lightColorScheme(primary = theme_color,background = theme_background_color
)/** 自定义主题 */
data class CustomThemeData(// 定义颜色val textColor: androidx.compose.ui.graphics.Color,// 定义形状// 定义字体var tag: Int = 10
)@Composable
fun darkCustomTheme() = CustomThemeData (textColor = text_aux33
)
@Composable
fun lightCustomTheme() = CustomThemeData (textColor = text_aux99
)
val CustomThemes = compositionLocalOf<CustomThemeData> { error("No Color provided") }val MaterialTheme.customScheme: CustomThemeData@Composable@ReadOnlyComposableget() = CustomThemes.current/** 主题 */
@Composable
fun RandomdtTheme(darkTheme: Boolean = isSystemInDarkTheme(),// Dynamic color is available on Android 12+dynamicColor: Boolean = false,  // 禁用动态颜色, 这样无论设备运行的Android版本如何,都会使用你定义的颜色方案. 启用了动态颜色时, 会在 Android 12+ 上覆盖自定义颜色方案。content: @Composable () -> Unit
) {val colorScheme = when {dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {val context = LocalContext.currentif (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)}darkTheme -> reDarkColorScheme()else -> reLightColorScheme()}CompositionLocalProvider(CustomThemes provides if (darkTheme) darkCustomTheme() else lightCustomTheme()) {MaterialTheme(colorScheme = colorScheme,typography = Typography,content = {// 使用MaterialTheme.colorScheme获取颜色, 必须放在MaterialTheme之内.val backgroundColor = MaterialTheme.colorScheme.backgroundval activity = LocalContext.current.findActivity()val view = LocalView.currentval window = (view.context as Activity).window// 设置状态栏SideEffect {activity?.window?.statusBarColor = backgroundColor.toArgb()WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme}content()})}
}
import android.app.Activity
import android.content.Context// 为 Context 类型定义的一个扩展函数
// 主要目的是从当前的 Context 对象中递归地寻找并返回一个 Activity 实例(如果存在的话)。这在 Android 开发中是很有用的,尤其是在需要在某些并非直接与 Activity 相关的代码(如工具类或扩展函数中)中访问 Activity 相关的功能时。
fun Context.findActivity(): Activity? = when (this) {is Activity -> thisis android.content.ContextWrapper -> baseContext.findActivity()else -> null
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/2182.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Lambda 禁止直接从公网访问

为了禁止 Lambda 直接从公网访问&#xff0c;您可以执行以下步骤&#xff1a; 更新 Lambda 函数的策略&#xff1a; 登录 AWS 控制台&#xff0c;导航至 Lambda 服务。找到需要修改的 Lambda 函数&#xff0c;并进入其配置页面。在函数配置页面&#xff0c;找到与 Lambda 函数…

7-17 KMP模式匹配算法

给定主串s和模式串p&#xff0c;编写程序使用KMP算法进行模式匹配&#xff0c;计算p在s中出现的首位置&#xff0c;若p不在s中则输出−1。字符串下标从0开始。 输入格式: 输入为2行&#xff0c;第1行为主串s&#xff0c;第2行为模式串p。主串和模式串长度不超过105。 输出格…

MVC4自带的JS、CSS优化功能

方法: Application_Start事件中 或 类 BundleConfig中的RegisterBundles方法中 加入代码: BundleTable.EnableOptimizations true;//是否启用优化 说明: 所说的JS、CSS优化&#xff1a; 缓存&#xff1a;首次访问站点&#xff0c;JS和CSS文件会下载到浏览器缓存中&#…

OpenCV-基于阴影勾勒的图纸清晰度增强算法

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 实现原理 大家在工作和学习中&#xff0c;无论是写报告还是论文&#xff0c;经常有截图的需求&#xff0c;比如图表、图纸等&…

使用 Docker 部署 TailChat 开源即时通讯平台

1&#xff09;介绍 TailChat 官网&#xff1a; https://tailchat.msgbyte.com/ 作者&#xff1a;https://www.moonrailgun.com/about/ GitHub &#xff1a; https://github.com/msgbyte/tailchat TailChat 是一款插件化易拓展的开源 IM 应用。可拓展架构赋予 Tailchat 无限可能…

【前端】vue的基础知识及开发指引

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Vue是什么二、学习 Vue.js 的基础知识三、熟悉 Vue.js 的生态系统四、掌握常用工具和库五、实践和项目开发六、 持续学习和跟进 前言 随着开发语言及人工智…

在不能升级版本的情况下,解决k8s证书到期且续约只有1年的问题

更新证书需要重启服务才能生效&#xff08;证书已经过期和还未过期都要重启才能生效&#xff09;&#xff0c;重启会对业务产生影响&#xff0c;请申请时间窗口进行处理 注意该工具只适用于k8s版本v1.18.5、请按照服务器架构选择对应的版本 相关说明&#xff1a; 证书到期后…

目标检测YOLO实战应用案例100讲-基于多尺度特征融合的水下小目标检测方法研究(下)

目录 2.4 基于两阶段的Faster R-CNN目标检测算法 2.5 目标检测数据集和评价标准

使用Docker搭建本地Nexus私有仓库

0-1开始Java语言编程之路 一、Ubuntu下Java语言环境搭建 二、Ubuntu下Docker环境安装 三、使用Docker搭建本地Nexus Maven私有仓库 四、Ubuntu下使用VisualStudioCode进行Java开发 你需要Nexus Java应用编译构建的一种主流方式就是通过Maven, Maven可以很方便的管理Java应用的…

全国832个贫困县名单及精准扶贫脱贫(摘帽名单)数据(2016-2020.11)

01、数据简介 自党的十八大以来&#xff0c;我国脱贫攻坚战取得了举世瞩目的伟大胜利。经过全党全国各族人民的共同努力&#xff0c;现行标准下9899万农村贫困人口全部脱贫&#xff0c;832个贫困县全部摘帽&#xff0c;12.8万个贫困村全部出列&#xff0c;区域性整体贫困得到解…

金融风控信用评分卡建模(Kaggle give me credit数据集)

1 数据预处理数据 数据来源于Kaggle的Give Me Some Credit&#xff0c;包括25万条个人财务情况的样本数据 1.1 导包读数据 import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.ensemble import RandomForestRegressor import seaborn as …

Excel图表智能排序

实例需求&#xff1a;表格中的多个图表如下图左侧所示&#xff0c;对于表格进行排序时&#xff0c;希望第一列中的图表跟随相应数据。 方法1&#xff1a; Sub SortTableWithChart()Dim oSht As Worksheet, RowCnt As Long, ColCnt As LongDim arrData, i As Long, oCht As Cha…

基于STM32CubeMX的嵌入式开发基础

内部没有上拉电阻&#xff0c;外部就要加一个 上拉或者下拉电阻&#xff0c;最基本上的作用是将状态不确定的信号通过一个电阻将其稳定在高电平或低电平 上拉下拉其实起的是稳定电平的作用 问题&#xff1a;单片机的外围电路设计及程序编写大多是以低电平有效来驱动电路的&…

【主流电商API接口数据采集】聚合电商API接口平台:让数据成为生产力!

API接口接入测试||文档 随着数字化商业时代的到来&#xff0c;API接口已成为电商资源连接利器&#xff0c;也是全球传统互联网企业转型的基础。 2021年 Google Cloud 研究显示&#xff0c;全球互联网企业近3/4的企业持续投入数字化转型&#xff0c;2/3的企业在持续增加投入&a…

轻松学会微信小程序开发(一)

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

Java进阶-Stream流

概述 在Java8中&#xff0c;得益于lambda所带来的函数式编程&#xff0c;引入了一个全新的Stream流的概念目的&#xff1a;用于简化集合和数组操作的api 案例 需求&#xff1a;创建一个集合存储多个字符串元素&#xff0c;将集合中所有以“z”开头的元素存储到新的集合中&am…

Torch 模型 感受野可视化

前言&#xff1a;感受野是卷积神经网络 (CNN) 中一个重要的概念&#xff0c;它表示 CNN 每一层输出的特征图上的像素点在输入图像上映射的区域。感受野的大小和形状直接影响到网络对输入图像的感知范围和精度&#xff0c;进而调整网络结构、卷积核大小和步长等参数&#xff0c;…

javaweb-maven

前端HTML,CSS,JS,Vue&#xff0c;Element&#xff0c;Nginx最后去复习&#xff0c; Java开发工程师 主要学习方向是服务端 所以进入javaweb的服务端的第一个知识点 maven 什么是maven 用于管理和构建java项目的工具 maven的官方网站 Maven – Welcome to Apache Maven …

Flink面试(1)

1.Flink 的并行度的怎么设置的&#xff1f; Flink设置并行度的几种方式 1.代码中设置setParallelism() 全局设置&#xff1a; 1 env.setParallelism(3);  算子设置&#xff08;部分设置&#xff09;&#xff1a; 1 sum(1).setParallelism(3) 2.客户端CLI设置&#xff0…

邀请全球创作者参与 The Sandbox 创作者训练营

作为首屈一指的元宇宙平台之一&#xff0c;The Sandbox 的使命是成为全球创作者的中心。随着我们对 Game Maker 的不断改进、旨在激发创作者灵感的定期 Game Jams、革命性的 "创作者挑战 "以及众多其他活动的开展&#xff0c;我们见证了大量个人加入我们充满活力的创…