我有一个可自定义主题的应用。用户当前可以在3个主题之间切换,每个主题改变主显示区域的背景颜色,字体颜色和字体,但不改变按钮或其他小部件。由于没有非常好的方法在主题中指定自定义字体,我的应用程序代码正在切换字体(使用Typeface.CreateFromAsset
和TextView.Typeface
)并重置主题(使用{{1} })。 (我相信这些的非Xamarin版本是SetTheme
,Typeface.createFromAsset
和TextView.setTypeface
,BTW。)但是我注意到,与其他字体相比,花哨字体看起来更小,所以每当我使用时那个主题我希望字体更大。所以我创建了以下主题,继承自我的主题:
setTheme
textSize属性通过主文本完成我想要的内容,使其更大。我无法弄清楚的是如何安排我的属性或样式,使其不影响其他文本。请注意,在我的截图中,当我使用此主题时,按钮文本也会变大。
理想情况下,我认为我希望主题能够指定仅适用于主视图的属性,例如:
<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似乎影响主视图中的文本,但不影响按钮。但是不存在这样的属性。
我不确定这是否可能,或者我是否从错误的方向接近这一点。
答案 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。