提问者:小点点

如何专业地组织纽扣的造型?(SDK 26+,最小SDK 21)


这个问题是可以回答的,因为材料设计的来源和Android Studio的设置都提供了足够的线索和示例,说明了预期的专业用法的模式。当然,用户并不局限于这些模式,而是遵循这些模式,使应用程序与Material Design的源代码一起运行良好,并提供最佳的可维护性。

我找到了几个与按钮造型相关的成分。

  • @style/widget.appcompat.button
  • @style/widget.appcompat.button.colored
  • @style/textappalance.appcompat.button
  • @style/textappearance.appcompat.widget.button
  • @color/foreground_material_dark
  • ?ColorAccent
  • ?TextColorPrimary
  • ?Android:ColorForeground
  • ?TextAppealanceButton
    null

你可以查资料来源。然而,即使知道所有细节,也不能给出预期使用的全貌。这个问题是要求画出图画。


共1个答案

匿名用户

(最小SDK 21)

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

代价是,每个按钮都需要两种设置:

    null
<Button
 style="?defaultButtonStyle"
<Button
 style="?defaultButtonStyle"
 android:textAppearance="?smallButtonTextAppearance"

如果我不打算使用不同的主题,我可以将样式直接设置到布局中。

<Button
 style="@style/My.DefaultButtonStyle"
 android:textAppearance="@style/My.SmallButtonTextAppearance"
 ...

如果a想要能够交换主题,我首先将所有类型的样式映射到属性。然后通过使用属性间接设置样式。这使我可以选择为其他主题连接其他样式,而不需要重复布局。

<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>

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

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

与其接触几十个不同的地方,不如在这里设置通用的默认文本颜色,并依赖于Android的默认颜色计算系统。在细节上调整一下。

<item name="android:colorForeground">@color/orange_700</item>

此设置默认为@color/foreground_material_dark

提示1:如果使用Android Studio主题编辑器编辑设置,可能会更改@color/foreground_material_dark的值。对我来说,改变物质黑暗的价值不是一个好主意,因为这不是我的领域。最好使用前面所示的引用。

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

提示3:使用?android:colorforeground不符合API 26下面的
框。如需变通方法,请参阅此处。

文本大小是文本外观的因素,我通常想直接调整到我自己的设计,在我自定义的文本外观样式。

<style name="My.SmallButtonTextAppearance" parent="My.DefaultButtonTextAppearance">
    <item name="android:textSize">16sp</item>
</style>
<item name="textAllCaps">true</item>
<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适用于按钮文本。为了进一步定制字体,我指出这个问题。

除了为背景使用颜色之外,还可以应用xml资源文件来指定具有花哨角、颜色渐变或其他图形效果的背景,还可以为按钮的不同状态支持不同的背景。

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

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

根元素是widget.material.button。它将默认文本外观设置为?textappearanceButton。因此,设置这个属性是一个选项,可以直接使用材质设计按钮样式,而不需要继承,同时还可以拥有自定义的默认文本外观。

<!-- 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.Colord的颜色。请参阅Android Studio主题编辑器。请参阅@drawable/btn_colored_material

<!-- 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/code>继承自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继承我自己的按钮样式。这使得继承的层次结构更低,代码更易读。如果我从另一种样式继承,它最多为我节省三行代码,而代码的可维护性变差了。

这个经验法则也有例外。例如,@drawable/btn_borderless_material是私有的。所以我要么继承widget.material.button.colored要么创建该文件的副本。

  • 定义自定义属性
  • Android使用自定义主题修改样式属性
  • Android“?ColorPrimary”vs“?attr/ColorPrimary”?
  • 使用属性androidTextapperance与属性样式时的继承问题
  • 根据主题设置颜色
  • 属性android:ColorForeground不在API 23 android主题中工作-在自定义主题中定义颜色
    null