gpt4 book ai didi

android - 如何专业地组织按钮的样式? (SDK 26+,最低 SDK 21)

转载 作者:行者123 更新时间:2023-12-03 15:51:40 24 4
gpt4 key购买 nike

组织专业 android 应用程序按钮样式的最佳做法是什么?假设有一个更大的当代应用程序(SDK 26+,最小 SDK 21)。

这个问题是可以回答的,因为Material Design的两个来源以及 Android Studio 的设置提供足够的线索和示例,说明预期的专业用途的模式。当然,用户不仅限于这种模式,但遵循它们,可以使应用程序与 Material Design 的来源一起很好地发挥作用。并提供最佳的可维护性。

我发现了几个与按钮样式相关的成分。

  • @style/Widget.AppCompat.Button
  • @style/Widget.AppCompat.Button.Colored
  • @style/TextAppearance.AppCompat.Button
  • @style/TextAppearance.AppCompat.Widget.Button
  • @color/foreground_material_dark
  • ?colorAccent
  • ?textColorPrimary
  • ?android:colorForeground
  • ?textAppearanceButton

  • 可能还有更多。
  • 所有的成分是如何相关的?
  • 它们打算如何在专业主题中一起使用?

  • 你可以查一下资料。但是,即使了解所有细节也不能全面了解预期用途。这个问题是要求画图。

    最佳答案

    (最低 SDK 21)

    一般的做法

    粒度

    我认为这是将文本外观与背景分开的足够细粒度的方法。这提供了将不同背景与不同文本外观相结合的选项。它还匹配 Button 提供的两种样式设置和 Material Design 的组织。因此,它解决了如何使用它的问题。

    价格是,每个Button需要两个设置:

  • 按钮文字:android:textAppearance
  • 按钮背景:style

  • 甚至更低的价格 styles_material.xml实际上采取了一种先进的方法。每个按钮 style已经包含默认文本外观。所以在正常情况下,我只需要应用按钮 style .
    <Button
    style="?defaultButtonStyle"

    我遵循这种模式来设计我自己的按钮样式,因为问题是针对预期用途的。如果我想修改默认值,我通过将其设置为 android:textAppearance 来添加替代文本外观。 .
    <Button
    style="?defaultButtonStyle"
    android:textAppearance="?smallButtonTextAppearance"

    对于非常特殊的按钮,我仍然可以在布局文件级别调整样式。这是最低级别的粒度。

    Hint: Be aware that android:textAppearance has a very low precedence. If you set a text attribute somewhere in the theme (or style), you will overwrite the same attribute in all of android:textAppearance. It works with a similar force like the "!important" annotation in CSS, which can be a pretty pitfall.



    灵活的主题

    没有

    如果我不打算使用不同的主题,我可以直接在布局中设置样式。
    <Button
    style="@style/My.DefaultButtonStyle"
    android:textAppearance="@style/My.SmallButtonTextAppearance"
    ...



    如果希望能够交换主题,我首先将所有类型的样式映射到属性。然后我通过使用属性间接设置样式。这使我可以选择连接其他主题的其他样式,而无需复制布局。
    <Button
    style="?defaultButtonStyle"
    android:textAppearance="?smallButtonTextAppearance"
    ...

    我个人不喜欢使用或混合给定的属性,而是完全定义我自己的一组属性来解决我的设计。所以洋葱的层次保持干净的分开。
    <?xml version="1.0" encoding="utf-8" ?>
    <resources>

    <!-- button text appearance -->
    <attr name="defaultButtonTextAppearance" format="reference" />
    <attr name="smallButtonTextAppearance" format="reference" />

    <!-- button backgrounds -->
    <attr name="defaultButtonStyle" format="reference" />
    <attr name="alarmButtonStyle" format="reference" />

    在主题中,属性被映射到主题特定的样式。
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    <style name="OtherTheme" parent="Theme.AppCompat">

    <!-- button text appearance -->
    <item name="defaultButtonTextAppearance">@style/OtherTheme.DefaultButtonTextAppearance</item>
    ...

    <!-- button backgrounds -->
    <item name="defaultButtonStyle">@style/OtherTheme.DefaultButtonStyle</item>
    ...

    按钮文字

    如果我将样式追踪到来源,我会找到一个文件 data/res/values/styles_material.xml ,它定义了所有按钮文本外观的根。 TextAppearance.Material.Button继承自 TextAppearance.Material ,但按钮的四个相关属性被覆盖。
    <style name="TextAppearance.Material">
    <item name="textColor">?attr/textColorPrimary</item>
    <item name="textColorHint">?attr/textColorHint</item>
    <item name="textColorHighlight">?attr/textColorHighlight</item>
    <item name="textColorLink">?attr/textColorLink</item>
    <item name="textSize">@dimen/text_size_body_1_material</item>
    <item name="fontFamily">@string/font_family_body_1_material</item>
    <item name="lineSpacingMultiplier">@dimen/text_line_spacing_multiplier_material</item>
    </style>

    <style name="TextAppearance.Material.Button">
    <item name="textSize">@dimen/text_size_button_material</item>
    <item name="fontFamily">@string/font_family_button_material</item>
    <item name="textAllCaps">true</item>
    <item name="textColor">?attr/textColorPrimary</item>
    </style>

    它可以被我自己继承的样式覆盖。它还表明,在不使用继承的情况下编写我自己的文本外观样式会很容易。

    颜色

    了解Android的文本颜色管理系统是他们最困惑的部分,因为该系统相当强大。这里有一些启示。

    在上面 TextAppearance.Material.Button我发现文本颜色由属性 ?textColorPrimary 指定.此属性再次基于属性 ?android:colorForeground .

    属性 ?android:colorForeground是设置文本颜色的中央开关。默认情况下,所有文本颜色都是基于此设置计算的,按钮的颜色也是如此。例如,为禁用按钮、正文等计算不同等级的灰色或不透明变体。

    与其接触几十个不同的地方,不如在这里设置常见的默认文本颜色,并尽可能依赖默认的 Android 颜色计算系统。在细节上调整它。
    <item name="android:colorForeground">@color/orange_700</item>

    此设置默认为 @color/foreground_material_dark .

    Hint 1: If you edit the setting by use of the Android Studio Theme Editor, it will possibly change the value of@color/foreground_material_dark. To me it does not feel like a good idea to change a value of material dark because it is not my realm. Better use a reference like shown before.

    Hint 2: The Theme Editor is an appropriate tool to discover the relations of the color attributes system. This relations reveal, when you experimentally try to edit the different attributes with the editor.



    如果我想要一个与整体文本颜色不同的按钮文本颜色,我将它设置在文本外观样式的级别上。

    Hint 3: Using ?android:colorForeground does not work out of the
    box below API 26. For a workaround see here.



    字体大小

    文本大小是文本外观的因素,我通常希望在我自定义的文本外观样式中直接调整到我自己的设计。
    <style name="My.SmallButtonTextAppearance" parent="My.DefaultButtonTextAppearance">
    <item name="android:textSize">16sp</item>
    </style>
    TextAppearance.Material.Button从资源中获取文本大小默认值 @dimen/text_size_button_material .没有与文本颜色设置系统相比具有中央文本大小设置的系统。

    全部大写

    根样式 TextAppearance.Material.Button将所有大写设置为 true .甚至没有资源,值(value)是从中获取的。它只是硬编码。
    <item name="textAllCaps">true</item>

    很有可能,我想设置为 false在我定制的按钮样式中。
    <item name="android:textAllCaps">false</item>

    字体系列

    与文本颜色一样,字体系列通常是一个具有共同中心性质的系统。按钮是如何管理的?根样式 TextAppearance.Material.Button使用字符串资源 @string/font_family_button_material .
    <item name="fontFamily">@string/font_family_button_material</item>

    在文件中 data/res/values/donttranslate_material.xml这被设置为 sans-serif-medium , 而在文件 data/res/values-watch/donttranslate_material.xml 中设置为 sans-serif-condensed .
    <string name="font_family_button_material">sans-serif-medium</string>
    <string name="font_family_button_material">sans-serif-condensed</string>

    sans-serif设置映射到我在字体设置中选择的字体系列。通常 sans-serif适用于按钮文本。为了进一步自定义字体,我指向 this question .

    按钮样式

    除了为背景使用颜色外,还可以应用xml资源文件来指定带有花哨角、颜色渐变或其他图形效果的背景,还支持 different backgrounds for different states of the button .

    这部分受我的设计影响很大。我通常会使用我自己的背景。

    另一方面,Material Design 中有丰富的预定义按钮背景资源文件系统。我想在这里做一个简短的概述,但这超出了我的技能范围,而且看起来太大了,值得单独讨论一个话题。
    style背景不应包含 width 的设置, heightmargins ,因为这属于周围的布局。另一方面 padding属于后台 style .

    Material Design 的按钮样式

    在文件中 data/res/values/styles_material.xml我找到了九种可以继承的按钮样式。如果我自己写,不要忘记设置默认文本外观。

    根元素是 Widget.Material.Button .它将默认文本外观设置为 ?textAppearanceButton .因此,设置此属性是一个选项,可以直接使用 Material Design 按钮样式而无需继承,但具有自定义的默认文本外观。
    <!-- Bordered ink button -->
    <style name="Widget.Material.Button">
    <item name="background">@drawable/btn_default_material</item>
    <item name="textAppearance">?attr/textAppearanceButton</item>
    <item name="minHeight">48dip</item>
    <item name="minWidth">88dip</item>
    <item name="stateListAnimator">@anim/button_state_list_anim_material</item>
    <item name="focusable">true</item>
    <item name="clickable">true</item>
    <item name="gravity">center_vertical|center_horizontal</item>
    </style>

    属性 ?colorAccent用于设置 Widget.AppCompat.Button.Colored的颜色.见 Android Studio Theme Editor .见 @drawable/btn_colored_material .

    注意 Widget.AppCompat.Button.Colored的默认文本外观变化并且不是由可定制的属性设置的。
    <!-- Colored bordered ink button -->
    <style name="Widget.Material.Button.Colored">
    <item name="background">@drawable/btn_colored_material</item>
    <item name="textAppearance">@style/TextAppearance.Material.Widget.Button.Colored</item>
    </style>

    <!-- Small bordered ink button -->
    <style name="Widget.Material.Button.Small">
    <item name="minHeight">48dip</item>
    <item name="minWidth">48dip</item>
    </style>

    <!-- Borderless ink button -->
    <style name="Widget.Material.Button.Borderless">
    <item name="background">@drawable/btn_borderless_material</item>
    <item name="stateListAnimator">@null</item>
    </style>

    注意 Widget.Material.Button.Borderless.Colored的默认文本外观变化并且不是由可定制的属性设置的。
    <!-- Colored borderless ink button -->
    <style name="Widget.Material.Button.Borderless.Colored">
    <item name="textAppearance">@style/TextAppearance.Material.Widget.Button.Borderless.Colored</item>
    </style>

    请注意 Widget.Material.Button.ButtonBar.AlertDialog继承自 Widget.Material.Button.Borderless.Colored .适用于默认文本外观的相同限制。
    <!-- Alert dialog button bar button -->
    <style name="Widget.Material.Button.ButtonBar.AlertDialog" parent="Widget.Material.Button.Borderless.Colored">
    <item name="minWidth">64dp</item>
    <item name="minHeight">@dimen/alert_dialog_button_bar_height</item>
    </style>

    <!-- Small borderless ink button -->
    <style name="Widget.Material.Button.Borderless.Small">
    <item name="minHeight">48dip</item>
    <item name="minWidth">48dip</item>
    </style>

    <style name="Widget.Material.Button.Inset">
    <item name="background">@drawable/button_inset</item>
    </style>

    <style name="Widget.Material.Button.Toggle">
    <item name="background">@drawable/btn_toggle_material</item>
    <item name="textOn">@string/capital_on</item>
    <item name="textOff">@string/capital_off</item>
    </style>

    就我个人而言,我要么使用这种预定义的按钮样式之一,要么从 Widget.Material.Button 继承我自己的样式。 .这使继承的层次结构保持在较低水平并且代码易于阅读。如果我从另一种风格继承,它最多可以节省我三行代码,而代码变得更不易维护。

    这条经验法则也有异常(exception)。例如 @drawable/btn_borderless_material是私有(private)的。所以我要么必须继承 Widget.Material.Button.Colored或创建文件的副本。

    附录

    相关问题

    属性
  • Defining custom attrs
  • Android Use custom themes to modify style attributes
  • Android "?colorPrimary" vs "?attr/colorPrimary"?
  • Inheritance issue, when using property androidTextapperance vs. property style

  • 颜色
  • Setting a color based on theme
  • Attribute android:colorForeground not working in API 23
    android themes - defining colours in custom themes

  • 字体
  • How to set default font family for entire Android app
  • How to change fontFamily of TextView in Android
  • What is the difference between fontFamily and typeFace in android?
  • 关于android - 如何专业地组织按钮的样式? (SDK 26+,最低 SDK 21),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50424396/

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