Android自定义样式继承

时间:2018-01-27 19:42:57

标签: android xml xamarin fonts themes

我有一个可自定义主题的应用。用户当前可以在3个主题之间切换,每个主题改变主显示区域的背景颜色,字体颜色和字体,但不改变按钮或其他小部件。由于没有非常好的方法在主题中指定自定义字体,我的应用程序代码正在切换字体(使用Typeface.CreateFromAssetTextView.Typeface)并重置主题(使用{{1} })。 (我相信这些的非Xamarin版本是SetThemeTypeface.createFromAssetTextView.setTypeface,BTW。)但是我注意到,与其他字体相比,花哨字体看起来更小,所以每当我使用时那个主题我希望字体更大。所以我创建了以下主题,继承自我的主题:

setTheme

textSize属性通过主文本完成我想要的内容,使其更大。我无法弄清楚的是如何安排我的属性或样式,使其不影响其他文本。请注意,在我的截图中,当我使用此主题时,按钮文本也会变大。

默认主题

Screenshot with default font

花式主题

Screenshot with fancy font

理想情况下,我认为我希望主题能够指定仅适用于主视图的属性,例如:

<style name="Theme.StoryvoqueFancy" parent="@style/Theme.StoryvoqueLight">
   <item name="android:textSize">18sp</item>
   <item name="android:lineSpacingExtra">5sp</item>
   <item name="android:textColorTertiary">#000000</item>
</style>

然后我会以某种方式从我的TextView引用mainViewTextSize。或者我想使用:

<item name="mainViewTextSize">18sp</item>

因为textColorTertiary似乎影响主视图中的文本,但不影响按钮。但是不存在这样的属性。

我不确定这是否可能,或者我是否从错误的方向接近这一点。

2 个答案:

答案 0 :(得分:1)

可以将文件attrs.xml添加到Resources\values\目录,其内容如下:

<?xml version="1.0" encoding="utf-8" ?>
<resources>
   <attr name="mainViewTextSize" format="dimension"/>
</resources>

定义自定义属性名称。

可以在themes.xml文件中引用此属性,如下所示:

<style name="Theme.StoryvoqueFancy" parent="@style/Theme.StoryvoqueLight">
   <item name="mainViewTextSize">18sp</item>
   <item name="android:textColorTertiary">#000000</item>
</style>

然后axml布局文件可以像这样引用它:

<TextView
    android:id="@+id/descriptionText"
    android:layout_height="wrap_content"
    android:layout_width="match_parent" 
    android:textSize="?mainViewTextSize" />

但是,似乎有必要在每个主题中定义mainViewTextSize,否则会遇到错误:

  

未处理的例外:

     

Android.Views.InflateException:二进制XML文件行#1:二进制XML文件行#1:发生错误类通知

避免递归似乎很重要(不要将mainViewTextSize的值默认为android:textSize)否则会遇到同样的错误。

更新

考虑到其他答案后,我已经到达以下themes.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <style name="TextAppearance.Storyvoque.MainView" parent="@android:style/TextAppearance.DeviceDefault" />
   <style name="Theme.StoryvoqueLight" parent="@android:style/Theme.DeviceDefault.Light.DarkActionBar">
      <item name="android:actionBarSize">32dip</item>
      <item name="android:actionBarStyle">@style/Theme.StoryvoqueLight.ActionBar</item>
      <item name="mainViewStyle">@style/TextAppearance.Storyvoque.MainView</item>
   </style>
   <style name="Theme.StoryvoqueLight.ActionBar" parent="@android:style/Widget.DeviceDefault.Light.ActionBar.Solid">
      <item name="android:titleTextStyle">@style/Theme.StoryvoqueLight.ActionBar.TitleTextStyle</item>
   </style>
   <style name="Theme.StoryvoqueLight.ActionBar.TitleTextStyle" parent="@android:style/Widget.Material.ActionBar.Solid">
      <item name="android:textSize">18sp</item>
   </style>
   <style name="Theme.StoryvoqueRetro" parent="@android:style/Theme.DeviceDefault">
      <item name="android:actionBarSize">32dip</item>
      <item name="android:actionBarStyle">@style/Theme.StoryvoqueLight.ActionBar</item>
      <item name="android:windowBackground">@android:color/background_dark</item>
      <item name="mainViewStyle">@style/TextAppearance.Storyvoque.Retro</item>
   </style>
   <style name="TextAppearance.Storyvoque.Retro" parent="@android:style/TextAppearance.DeviceDefault">
      <item name="android:textColor">#00FF00</item>
   </style>
   <style name="Theme.StoryvoqueFancy" parent="@style/Theme.StoryvoqueLight">
      <item name="android:windowBackground">@color/papyrus</item>
      <item name="mainViewStyle">@style/Theme.StoryvoqueFancy.Text</item>
      <item name="android:lineSpacingExtra">8dp</item>
   </style>
   <style name="Theme.StoryvoqueFancy.Text" parent="@style/TextAppearance.Storyvoque.MainView">
      <item name="android:textSize">18sp</item>
      <item name="android:textColor">#000000</item>
   </style>
</resources>

我的axml文件包含:

<TextView
    android:id="@+id/descriptionText"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"            
    android:textAppearance="?mainViewStyle"

我的attrs.xml文件包含:

<?xml version="1.0" encoding="utf-8" ?>
<resources>
   <attr name="mainViewStyle" format="reference"/>
</resources>

我仍然不确定这是否理想,但它似乎比我之前的解决方案设计得更好,并且在没有任何进一步建议的情况下对我来说似乎已经足够好了。

答案 1 :(得分:1)

鉴于主题是全局样式是本地,您可能希望创建应用于{{的特定样式 1}}级别而不是全局。

据说你应该定义一个View,你的风格将继承并最终应用于你的TextAppearance。如果您需要对样式进行任何自定义,则可以创建custom style attributes