android开发theme,安卓开发:一文弄懂Theme与Style的区别,一起来看下吧

关于Android样式,系统提供了一种强大的方式来指定应用程序的视觉设计,但很容易被误用。正确使用它可以使主题和样式更容易维护,使更新不那么烦琐,并使其直接支持Dark模式。然而,在使用样式的时候,Theme与Style的概念我们还是要区分清楚。

Theme不等于Style

Theme和Style使用相同的

Style是视图属性的集合,特定于单一类型的小部件。

0b7b02087bf40ad10e170159c25f21d9a8ecce17.png?token=ff062c601630a1cbca912e7b58ee7ef7&s=B9A85032C5F448214AD945D20300C0B2

如图所示,Style中的每个键都是可以在布局中设置的:

8644ebf81a4c510fed5f8387f52a152bd52aa509.png?token=c4911cf2fce31501fa5ffa792e873b48&s=1C8A54324D625D20587D00DA0300C0B2

将它们提取为一种样式可以方便地跨多个视图重用和维护。

使用Style由布局中的各个视图使用:

7af40ad162d9f2d357124d65339fba156227ccb6.png?token=df1a509fd3883025f565d399472908f1

视图只能应用一个样式-与其他样式系统(如web上的css)相比,组件可以设置多个css类。

范围应用于视图的Style仅应用于该视图,而不应用于其任何子视图。例如,如果有一个带有三个按钮的ViewGroup,则在ViewGroup上设置InlineAction样式不会将该样式应用于按钮,Style提供的值与直接在布局中设置的值组合(使用样式优先顺序解析)。

什么是Theme?

Theme是命名资源的集合,这些资源稍后可以被样式、布局等引用。它们为Android资源提供语义名称,以便以后可以引用它们,例如colorPrimary是给定颜色的语义名称:

a8773912b31bb05193195d9ba209eab24aede03a.png?token=d60ab4211ceb4c2dc4a31c81052b7dc9&s=10984130C5344C234CE060D3030080B2

这些命名资源称为主题属性,因此主题是Map。主题属性不同于视图属性,因为它们不是特定于单个视图类型的属性,而是语义上命名的指向应用程序中更广泛适用的值的指针。主题为这些命名资源提供了具体的值。

在上面的示例中,color primary属性指定此主题的主颜色为teal。通过使用主题抽象资源,我们可以在不同的主题中提供不同的具体值(例如colorPrimary=orange)。

Theme是命名资源的集合,在应用程序中非常有用。

Theme类似于接口,接口编程允许您将公共契约与实现分离,从而允许您提供不同的实现。

Theme扮演着相似的角色,通过根据Theme属性编写布局和样式,我们可以在不同的主题下使用它们,提供不同的具体资源。

大致相当的伪代码:

377adab44aed2e73717fe1551372918d86d6faab.png?token=45ec4f82898dc7e761db0704f7b45d8b&s=39A07D320B624D201CFCB1DA0300C0B3

它允许我们改变MyView的呈现方式,而不必创建它的变体:

1c950a7b02087bf4e6a111de66a0672a11dfcf36.png?token=c2000f9dd258703f4f5f1d4818c6d875&s=3DA07D324B2645205A55F1DA0300C0B1

使用我们可以在具有(或是)上下文的组件上指定主题,例如活动或视图/视图组:

32fa828ba61ea8d344aa749a03790048241f5819.png?token=412b78ff512c6f5918b3b3cd53b3dc19&s=3CA85432177A40200CC521DA0300D0B2

还可以通过用CurrestMeTeWrPress包装现有的上下文来设置代码中的主题,然后可以使用该上下文来扩展布局等。

Theme的优点来自于如何使用它们,可以通过引用Theme属性来构建更灵活的小部件,不同的Theme在以后提供了具体的价值。例如,可能希望在视图层次结构的某个部分上设置背景色。

bf096b63f6246b60b7524393728b2a4a500fa277.png?token=146b7dd9f9ae77fada2a1a0180a1e78e

与其设置静态颜色(#ffffff或@color resource),不如使用“?attr/themeAttributeName”语法。

此语法表示:查询主题以获取此语义属性的值。这种间接层次允许我们提供不同的行为(例如,在明暗主题中提供不同的背景色),而无需创建多个布局或样式,这些布局或样式基本相同,但颜色变化很少。它隔离了主题中正在变化的元素。

使用“?attr/themeAttributeName”语法查询主题以获取此语义属性的值

范围Theme是作为上下文的属性访问的,可以从任何具有上下文的对象(如活动、视图或视图组)获取。这些对象存在于树中,其中活动包含包含视图的视图组等。指定树的任何级别上的主题级联到后代节点,例如在View组上设置主题适用于它内的所有视图(与仅适用于单个视图的样式相反)。

0823dd54564e92585adde78309f1e15ecdbf4e6f.png?token=4bcba5674eb324756227225d0fba7d21&s=2DA85C32CD664520587164DA0300C0B2

这是非常有用的,比如说,如果你想要一个Dark主题的部分,否则轻屏幕。

虽然Context提供了setTheme方法,或者Theme提供了applyStyle方法,但这些都需要在inflate之前调用,设置新主题或应用inflate后的风格不会更新现有视图。

区别对待

了解不同的职责以及Style和Theme之间的交互,有助于使样式资源更易于管理。

例如,假设你的应用程序有一个蓝色的主题,但是一些专业的屏幕有一个漂亮的紫色外观,你想为深色主题提供经过调整的颜色。如果只使用样式来实现此目的,则必须为Pro/non-Pro和light/dark的排列创建4个样式。由于样式特定于视图类型(按钮、开关等),因此您需要为应用程序中的每个视图类型创建这些排列。

c2fdfc039245d688c822692330b14d18d31b248a.png?token=cfd004ea3f5f3808b035f2060009bf72&s=F297016497AC3EAA40853D830200A09A

如果我们使用样式和主题,我们可以将按主题更改的部分隔离为主题属性,因此我们只需要为每个视图类型定义一个样式。对于上面的示例,我们可以定义4个主题,每个主题都为colorPrimary主题属性提供不同的值,然后这些样式引用并自动反映主题的正确值。

这种方法可能看起来更复杂,因为您需要考虑样式和主题的交互,但它有一个好处,即隔离每个主题更改的部分。

因此,如果你的应用程序从蓝色改名为橙色,你只需要在一个地方更改,而不是分散在你的风格,它也有助于对抗风格的扩散。

理想情况下,每个视图类型只有少量样式。如果不利用主题化的优势,styles.xml文件很容易失控,并爆发出类似样式的不同变体,这将使用我们的维护工作更加复杂。

举报/反馈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值