【问题标题】:Layout Attributes within Styles样式中的布局属性
【发布时间】:2019-10-31 17:39:12
【问题描述】:

我有一段时间陷入困境,我不知道如何正确解决它。我想使用 DRY(不要重复自己),但不要在样式中应用不良做法(例如在其中设置布局属性)。

这是我的情况...

为了在我的项目中封装文本样式,我通常使用以下内容:

我有一个风格叫Wrap_Content

<style name="WrapContent">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
</style>

一方面,我有一个名为Tv 的样式,它继承自WrapContent

<style name="Tv" parent="WrapContent">
    <item name="android:fontFamily">@font/font_foo</item>
    <item name="android:textColor">@color/color_foo</item>
</style>

如您所见,Tv 样式具有默认字体和文本颜色 例如,如果我想使用 15sp 的字体大小,我会应用这种样式:

<style name="Tv.15">
    <item name="android:textSize">15sp</item>
</style>

等等……

好吧,问题是我项目的所有TextView 都设置了wrap_content 的宽度和高度。 因此,这样做可以大大简化 XML 布局,并增加可读性和对常见行为进行分组。

例子:

<TextView
    style="@style/Tv.15"
    android:text="@string/foo"/>

如果在任何情况下,我想更改任何属性,我只需要从我调用它的地方覆盖它。

困境在于我将textAppearance 样式与layout 样式混合在一起。我曾考虑过将其分开……但我还没有解决主要问题,我正在为其设置布局属性,我应该只知道它自己的视图,而不是它的容器。

但完全不能说服我的是做这样的事情:

<style name="Tv">
    <item name="android:fontFamily">@font/font_foo</item>
    <item name="android:textColor">@color/color_foo</item>
</style>

<style name="Tv.15">
    <item name="android:textSize">15sp</item>
</style>

<TextView
    style="@style/Tv.15"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/foo"/>

如果这些属性很常见,我不想重复一百万次相同的属性。或者是的,我知道它会带来什么……技术债务。因此,它似乎不是一个有效的选项。

我已经搜索了很多,但事实是我没有找到任何能说服我的东西,我想找到一些优雅的东西,因为它是我一直使用的东西,但我不喜欢它。

嗯……你怎么看?

非常感谢!!!


2019 年 11 月 8 日编辑

我想到了一种添加新样式层的新方法,@style/TextAppearance。是这样的:

<style name="WrapContent">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
</style>

<style name="TextAppearance">
    <item name="android:fontFamily">@font/font_foo</item>
    <item name="android:textColor">@color/color_foo</item>
</style>

<style name="TextAppearance.15">
    <item name="android:textSize">15sp</item>
</style>

<style name="Tv" parent="WrapContent">
    <item name="android:textAppearance">@style/TextAppearance</item>
</style>

<style name="Tv.15">
    <item name="android:textAppearance">@style/TextAppearance.15</item>
</style>

这给系统增加了一点复杂性,但它拆分了布局和 textAppearance 属性。此外,它允许使用TextAppearance 样式的按钮,editTexts 等等。

【问题讨论】:

  • 如果您有一个textAppearance 样式和一个layout 样式,则不能将它们应用于相同的TextView,因为每个View 将只采用一个style="@style/..." 属性。所以不混合这两种属性似乎是不可能的。我不是设计大师,但最近我开始声明样式,因为某个 View 在我的应用程序中扮演的技术角色 - 标签应该在整个应用程序中具有一种风格,而标题应该是另一种风格。
  • 您可以将这两个东西(textAppearance 和样式)应用到同一个视图@0X0nosugar。好吧,以防万一它是一个TextView。但这不是问题... :-)
  • 我的意思是说你不能为同一个视图设置两个 style="@style/..." 属性。因此,不可能同时应用一种仅包含与布局相关的属性的样式和一种仅包含与同一视图外观相关的属性的样式。因此,尝试将这两个方面分开将不适用于 android,即使从架构 POV 来看这可能是一个好主意

标签: android android-layout android-styles


【解决方案1】:

在我们最近的 Android 开发者峰会上,我的两位同事就如何使用 Theme & Style 进行了演讲。我们建议您将主题用于视图组及其子项和样式以获取更简单的视图。也许您的布局需求可以通过使用主题然后为文本外观等保留样式来满足。除此之外,有效性应该指导您如何构建样式对象。

【讨论】:

  • 谢谢,以赛!我已经看过视频了。太棒了! :-)。我已经开始应用他们谈到的其中一项建议,?attr/color。关于样式,我想到了添加新样式层的其他方法。我已经编辑了答案以显示它;-)
  • 你所拥有的非常好。需要注意的是,由于您使用parent 来扩展WrapContent,因此您应该考虑使用点符号来使派生样式的名称更具描述性。也许像“WrapContent.TextAppearance.Tv”。所以解释一下这意味着什么:如果你定义了一个parent,那么系统会忽略点符号作为你命名你的风格的方式。此外,如果您的应用中有多个文本外观,TextAppearance 的描述性可能不够。 (命名片段使您一眼就能记住发生的事情”
  • 我喜欢!谢谢,以赛! :-)
  • 如果此答案为您提供了所需的方向,请考虑接受它以帮助其他用户/寻求者。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多