gpt4 book ai didi

android - Android中的编码样式:什么时候应该使用样式而不是内联属性?

转载 作者:行者123 更新时间:2023-11-29 14:31:07 37 4
gpt4 key购买 nike

我不确定在Android中开发界面的最佳方法是什么。
通过将内联属性移动到样式文件来清理布局文件是否更好?据我所知,在HTML中最好在HTML中使用类和ID,并在style.css文件中使用它们。 android呢?

最佳答案

我发现了这一点,也许对其他人有帮助。

何时使用样式

我们必须解决的第一个问题是一个简单的问题:什么时候应该使用样式而不是内联属性?

规则1:当多个视图在语义上相同时,请使用样式。

可以通过一些示例很好地说明此规则:


您正在创建一个计算器。每个按钮应该看起来相同,因此创建`CalculatorButton`样式是有意义的。
您有几个具有多种文本格式的屏幕-例如标题,子标题和文本。您可以通过创建`Header`,`Subheader`和`Text`样式来统一它们的外观。
您在整个应用中都有缩略图。您希望它们看起来都一样。 “缩略图”样式诞生了。


所有这些示例中的共同点是这些Views不仅使用相同的属性-它们在整个应用程序中扮演相同的角色。现在,当您想要调整任何这些Views的外观时,您只需编辑样式并立即更改它们即可。这样可以节省您的时间,精力,并使您的Views保持一致。



是否想节省更多工作?使用资源引用!

规则2:在适当时在样式内使用引用。

您可以通过以下方式定义样式:

<style name="MyButton">
<item name="android:minWidth">88dp</item>
<item name="android:minHeight">48dp</item>
</style>


如果您希望 minWidth根据屏幕大小变化怎么办?您可以按照每个屏幕尺寸(例如 sw600dpsw900dp)复制样式一次,但是随后还必须复制 minHeight属性。如果您想同时更改两个属性怎么办?突然,到处都有大量的 MyButtons定义,每个副本都复制了所有其他属性。这是灾难的秘诀;忘记更改多个副本之一中的一个属性是如此容易。

样式只是一系列属性的别名。像这样定义样式要容易得多:

<style name="MyButton">
<item name="android:minWidth">@dimen/button_min_width</item>
<item name="android:minHeight">@dimen/button_min_height</item>
</style>


现在,您只需为每个资源限定符修改一个属性。考虑复制布局只是为了改变(例如,纵向与横向的一个 View的宽度)是荒谬的。您可以为此使用尺寸。样式也一样。

我并不是说您应该始终在样式中使用资源引用;只是如果您需要在资源限定符上启用多个值,则应该使用它。

这并不是说有时候您不需要跨资源限定符复制样式,但是可以将其保持在最低限度。通常,这样做的唯一原因是由于平台更改(例如,从 paddingLeftpaddingRight更改为 paddingStartpaddingEnd)。

多种风格

如果您可以将多个样式应用于单个 View(如CSS),那将是很棒的。

你不能抱歉。

但是您可以在几种情况下获得多种样式的近似值。

规则3:使用主题调整默认样式。

主题提供了定义许多标准小部件的默认样式的方法。例如,如果要为应用程序定义默认按钮,则可以执行以下操作:

<style name="MyTheme">
<item name="android:buttonStyle">@style/MyButton</item>
</style>


如果您只是在调整默认样式,那么唯一棘手的部分就是确定样式的父样式。您希望它与设备的适当主题相匹配,但这取决于操作系统版本。

如果您使用的是AppCompat主题,则应将其样式用作父样式,因为它们也可以处理跨平台的差异。例如,它们具有 Spinner样式:

<style name="MySpinner" parent="Widget.AppCompat.Spinner" />


如果该样式在AppCompat中不存在(或者您没有使用它),则问题会有些棘手,因为您需要父级根据主题进行切换。这是一个自定义 Button样式的示例,该样式通常使用Holo,但在适当时使用Material。

您可以将其放在 /values/values.xml中:

<style name="ButtonParent" parent="android:Widget.Holo.Button />

<style name="ButtonParent.Mine">
<item name="android:background">@drawable/my_bg</item>
</style>


然后,在 /values-v21/values.xml中:

<style name="ButtonParent" parent="android:Widget.Material.Button />   


设置正确的父代将确保与您的应用程序和平台保持一致。

如果您确实想定义所有必要的属性(而不仅仅是调整默认值),则可以完全跳过育儿。

规则4:尽可能使用文字外观。

TextAppearance允许您为某些最常修改的文本属性合并两种样式。看一下您所有的样式:其中有多少只修改文本的外观?在这种情况下,您可以只修改 TextAppearance

首先,您需要定义您的 TextAppearance

<style name="MyTextAppearance" parent="TextAppearance.AppCompat">
<item name="android:textColor">#0F0</item>
<item name="android:textStyle">italic</item>
</style>


请注意,我是如何设置父项的-文本外观不会合并,因此您需要确保定义所有属性。您可以使用任何适当的 TextAppearance作为父项。

现在您可以在 TextView中使用它:

<TextView
style="@style/MyStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/MyTextAppearance" />


请注意,我仍然可以将样式应用于此 TextView,从而为一个视图提供了多达两种的样式!不如真正的多种样式好,但我会尽力而为。

您可以在扩展 TextAppearance的任何类中使用 TextView。这意味着 EditTextButton等都支持文本样式。

常见陷阱

我一直在解释使用样式的方式。不幸的是,很容易滥用样式,从长远来看会伤害您。这里有一些需要避免的反模式。

规则5:如果只使用一次,则不要创建样式。

样式是抽象的额外一层。它增加了复杂性。您必须查找样式以查看它们应用的属性。因此,除非您要在多个地方使用该样式,否则我认为没有理由使用它们。

打开布局时,您希望看到哪个:这?

<TextView style="HelloWorldTextView" />


或这个?

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />


如果需要,稍后创建样式非常容易。不要计划得太多。



规则6:请勿仅因为多个视图使用相同的属性而创建样式。

使用样式的主要原因是减少重复属性的数量,对吗?为什么当多个视图使用相同属性时不只是使用样式?

这种态度的问题在于,如果 Views不在同一上下文中使用,则最终可能希望它们的外观有所不同。到那时,如果没有意外的副作用,您的基本样式将变得难以编辑。

考虑这种情况:您有一些 TextViews相同的文本外观和背景。您认为,“嘿,我将创建一种样式,从而减少代码重复。”最初,一切都是笨拙的,但是最终您要调整 TextViews的外观。问题是,到目前为止,该样式已在各处使用,因此您不能在没有附带损害的情况下对其进行编辑。

很好,您说-我将直接在布局XML中覆盖样式。问题解决了。然后又发生了。然后再次。最终,这种风格毫无意义,因为您必须在任何地方都覆盖它。最终增加了额外的工作,而不是使生活更轻松。

这就是为什么我在规则#1中指定 Views在语义上相同时应该使用样式的原因。这样可以确保在更改样式时,您确实确实希望使用该样式的每个 View都进行更改。

内隐与外显育儿

样式支持育儿,其中子样式采用父样式的所有属性。如果他们不这样做,那将是相当有限的。

假设我希望应用程序中的每个 Button看起来都一样,所以我制作了 ButtonStyle。后来,我决定 Buttons的一半看起来应该稍有不同-通过育儿,我可以创建 ButtonStyle.Different,获得基本样式+调整。

事实证明,有两种隐式和显式定义父母的方式:

<!-- Our parent style -->
<style name="Parent" />

<!-- Implicit parenting, using dot notation -->
<style name="Parent.Child" />

<!-- Explicit parenting, using the parent attribute -->
<style name="Child" parent="Parent" />


很简单吧?但是,当我们用两种方法定义父母时,您认为这里会发生什么?

<style name="Parent.Child" parent="AnotherParent" />


如果您回答该样式有两个父母,那您错了。事实证明,它只有一个父对象: AnotherParent

每种样式只能有一个父项,即使有两种定义方式也可以。显式父级(使用属性)优先。这将我引至下一条规则:

规则7:请勿混用隐性和显性育儿。

混合两者是造成混乱的秘诀。假设我有这样的布局:

<Button
style="@style/MyWidgets.Button.Awesome"
android:layout_width="match_parent"
android:layout_height="match_parent" />


但是事实证明,我的风格是这样定义的:

<style name="MyWidgets.Button.Awesome" parent="SomethingElse" />


即使看起来我的 Button是基于 MyWidgets.Button的,但事实并非如此!样式名称具有误导性,并且发现样式的唯一方法是进行额外的工作并挖掘您的样式文件。

常见的诱惑是继续将点符号与显式育儿一起使用,以使样式看起来具有层次关系:

<style name="MyButton" parent="android:Widget.Holo.Button" />
<style name="MyButton.Borderless" parent="android:Widget.Holo.Button.Borderless" />


面向对象的样式!他们看起来好漂亮吧?但是,外观就是您所得到的一切-一种错觉的感觉,即样式无关。欺骗是 MyButton.BorderlessMyButton有关,但是它们没有共同之处!让我们通过删除名称中的点来消除混乱:

<style name="MyButton" parent="android:Widget.Holo.Button" />
<style name="MyBorderlessButton" parent="android:Widget.Holo.Button.Borderless" />


我在漂亮的层次结构上迷失了方向,但是我在代码中获得了很多实用性。

样式与主题

样式和主题是两个不同的概念。样式应用于单个 View时,主题应用于一组 Views(或整个 Activity)。

例如,假设您正在使用AppCompat,并且想要设置屏幕的原色。为此,您必须主题整个 Activity

<style name="MyTheme">
<style name="colorPrimary">@color/my_primary_color</style>
</style>


主题使用与样式相同的数据结构-甚至使用 style标记-但实际上它们在完全不同的情况下使用!它们不能使用相同的属性-例如,您可以在视图上定义 textColor,但是主题没有 textColor属性。同样,主题中存在 colorPrimary,但在样式中它们未使用。从而:

规则8:请勿混用样式和主题。

我见过两个常见的错误:


将主题(作为样式)应用于“视图”:

      

只是没有意义,因为“视图”无论如何都不能使用任何主题属性。什么都没发生。
通过育儿将主题/样式组合到层次结构中。我看到这是由于人们试图使用点表示法维护层次结构的错觉的结果:

    
    
    

Stupid! So, stupid!它没有任何意义,有时会以奇怪的方式失火。只是不要这样做!




从棒棒糖开始,您可以将主题应用于 View及其所有子项2。即使在这种情况下,也不要将两者混为一谈,尽管可以同时使用它们:

<View 
style="@style/MyView"
android:theme="@style/MyTheme" />


AppCompat的 View主题模拟为 Toolbar,但是直到Lollipop是应用程序的最低支持版本为止,您将获得一小段时间。换句话说-您可以在几年内使用此功能。 :P

结论

这些规则的统一要素是在使用样式时要谨慎周到。它们可以节省您的时间,但前提是您知道何时使用它们。

字体: this article

关于android - Android中的编码样式:什么时候应该使用样式而不是内联属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31102407/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com