放置XML样式的位置

时间:2018-01-25 15:27:07

标签: android android-toolbar android-theme android-styles

问题1

我希望所有Toolbar看起来都一样,而不是在所有colorControlNormal中设置样式, 所以我虽然我会为它设置应用程序主题。我希望他们拥有的一件事是<resources> <style name="MyTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="toolbarStyle">@style/MyTheme.ToolbarStyle</item> </style> <style name="MyTheme.ToolbarStyle" parent="@style/Widget.AppCompat.Toolbar"> <item name="colorControlNormal">@color/toolbarColorControlNormal</item> </style> </resources> 属性。这些是我的尝试:

代码示例1

<resources>
    <style name="MyTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorControlNormal">@color/toolbarColorControlNormal</item>
    </style>
</resources>

代码示例2

Toolbar

代码示例1 中,我尝试为tabTextColor属性创建自定义样式,并将其设置为主题,但它不起作用。

代码示例2 中,我将该属性设置为全局且有效。但是,也会影响其他组件,因此无效。

  • 为什么代码示例1 无效?

问题2

我需要更改所有tabSelectedTextColor的{​​{1}}和TabLayout属性,所以我尝试了这个:

代码示例3

<resources>
  <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:tabWidgetStyle">@style/TabsStyle</item>
  </style>

  <style name="TabsStyle" parent="Widget.Design.TabLayout">
    <item name="tabTextColor">@color/tabTextColor</item>
    <item name="tabSelectedTextColor">@color/tabSelectedTextColor</item>
  </style>
</resources>

但它没有用,我使用它的唯一方法是手动设置它们:

<android.support.design.widget.TabLayout
    [...]
    android:background="?android:attr/colorPrimary"
    app:tabTextColor="@color/tabTextColor"
    app:tabSelectedTextColor="@color/tabSelectedTextColor" />
  • 为什么代码示例3 无效?

最后,我会赞成任何对好风格的提及。主题指南/书籍。我真的需要改进。

提前致谢。

3 个答案:

答案 0 :(得分:4)

在全球范围内为Toolbar

中的后退箭头指定颜色

这并不像它应该的那样简单,但请尝试以下方法:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- style the back arrow -->
    <item name="toolbarNavigationButtonStyle">@style/NavButtonStyle</item>
</style>

<style name="NavButtonStyle" parent="@style/Widget.AppCompat.Toolbar.Button.Navigation">
    <item name="android:tint">#FF0000</item>
</style>

android:tint会改变后箭头的颜色。

通常,默认工具栏样式由属性toolbarStyle设置。在下面的XML中,它设置为@style/MyToolbarStyleMyToolbarStyle定义了三个将用于应用内所有工具栏的属性。这是一个人的样子:

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="toolbarStyle">@style/MyToolbarStyle</item>
        <item name="titleTextColor">@android:color/holo_red_light</item>
    </style>

    <style name="MyToolbarStyle" parent="@style/Widget.AppCompat.Toolbar">
        <item name="titleTextColor">@android:color/white</item>
        <item name="subtitleTextColor">@android:color/holo_green_light</item>
        <item name="android:background">@color/vermillion</item>
    </style>
</resources>

enter image description here

如您所见,MyToolbarStyle设置了三个属性的值。不幸的是,这种方法不适用于所有属性,例如colorControlNormal,如果在主题中指定,将改变后箭头的颜色。

关于TabLayout

的问题

全局定义TabLayout的属性没有漂亮的解决方案。您可以执行this之类的操作,只覆盖Widget.Design.TabLayout,但您必须重新创建其中定义的所有属性,这些属性可能会根据正在运行的版本而更改。这可行,但可能是一个需要维护的问题。我不认为这是一个很好的解决方案。

另一种解决方案是创建自己的自定义TabLayout。它将非常简单,只需将tabTextAppearance定义为TabLayout的全局默认属性。整个自定义布局如下所示:

public class MyTabLayout extends TabLayout {
    public MyTabLayout(Context context, AttributeSet attrs) {
        super(context, attrs, R.attr.tabTextAppearance);
    }
}

TabLayout的所有引用替换为MyTabLayout后,您将能够在styles.xml中执行以下操作:

<style name="AppTheme" parent="BaseAppTheme">
    <item name="tabTextAppearance">@style/MyTabStyle</item>
</style>

<style name="MyTabStyle" parent="Widget.Design.TabLayout">
    <item name="tabTextColor">#FF0000</item>
    <item name="tabSelectedTextColor">#00FF00</item>
</style>

这会使标签文本颜色显示为红色和绿色,但它们可以是您选择的颜色。您现在可以在XML中声明TabLayout并使用默认样式,而无需显式指定样式/主题。

根本问题是TabLayout的CTOR不使用defStyleResource,它定义了应用于主题中定义的视图的默认样式,tabWidgetStyle不是它。 。(请参阅this。)自定义布局MyTabLayout可以解决问题。然而,这确实提出了一个问题,即是否有defStyleResource没有使用的原因,也许我们正在潜入一个我们可能最好避免的石楠补丁。

这些方法确实有效,但我还没有对它们进行全面测试。您必须确定是否更好地执行此处描述的操作,或者仅在逐个视图的基础上定义样式。

如果有人使用Android批准的标准方式在全球范围内指定TabLayout属性,我将很高兴听到它。

答案 1 :(得分:1)

问题1

主题风格之间的区别是微妙的,因为你使用{{1}来定义它们,所以事情比它们应该更加困惑。 } 标签。但即使它们都使用<style>标签,它们的行为也不同。

视图的主题中指定的属性适用于该视图及其所有子视图。视图的样式中指定的属性仅适用于该视图。此外,还有一些名为主题属性的属性仅在它们成为主题的一部分时才起作用。 <style>是主题属性;将它设置为一种风格不会产生任何影响。

代码示例1 不起作用,因为您的colorControlNormal元素是以样式而非主题定义的。

代码示例2 会更改所有内容,因为现在<item name="colorControlNormal">位于应用主题中,因此它适用于您关注的应用中的所有元素关于它。

不幸的是,我认为没有办法只为您的应用中的每个colorControlNormal指定一个主题。您必须满足以下条件之一:

1)使用Toolbar属性

为此,您需要创建一个样式:

android:theme

然后,在每个<style name="MyToolbarTheme"> <item name="colorControlNormal">@color/toolbarColorControlNormal</item> </style> 代码上添加

<Toolbar>

2)创建android:theme="@style/MyToolbarTheme"

的自定义子类

同样,你需要一种像上面这样的风格。然后你要创建一个这样的类:

Toolbar

并在您的布局文件中使用它:

public class MyToolbar extends Toolbar {

    public MyToolbar(Context context, AttributeSet attrs) {
        super(wrapContext(context), attrs);
    }

    private static Context wrapContext(Context context) {
        return new ContextThemeWrapper(context, R.style.MyToolbarTheme);
    }
}

这可以通过获取工具栏正在膨胀的<com.example.stackoverflow.MyToolbar android:layout_width="match_parent" android:layout_height="wrap_content"/> 实例并将其主题更改为自定义工具栏主题来实现。由于此(包装)上下文仅用于创建自定义工具栏,因此不会影响应用中的其他视图。

为了它的价值,这就是我在我的应用中所做的。

问题2

此处,为什么更简单:ContextTabWidget的默认样式,而不是android:tabWidgetStyle。实际上,我并不知道TabLayout的任何已定义的默认样式。

同样,您有两种选择。您可以创建一个样式并将其应用于每个TabLayout标记,或者您可以创建一个自定义子类并使用它而不是<TabLayout>

TabLayout

进一步阅读

这是我在学习这些东西时读到的一些材料:

https://developer.android.com/guide/topics/ui/look-and-feel/themes.html

https://medium.com/google-developers/theming-with-appcompat-1a292b754b35

https://www.androiddesignpatterns.com/2016/08/contextcompat-getcolor-getdrawable.html

答案 2 :(得分:-1)

右键单击res文件夹,选择New - &gt; Android资源文件,为新文件设置相同的名称&#34; styles&#34;,在可用限定符中:选择最后一项&#34;版本&#34;最后设置&#34;平台API级别&#34; 21。