Android:通过样式

时间:2016-02-03 14:18:57

标签: android alertdialog android-theme android-styles

我正在尝试通过样式更改警告对话框中的邮件字体大小,但我无法使其正常工作。有很多答案描述了如何做到这一点,但我发现几乎所有这些都是以编程方式进行的。我希望在样式中执行一次,而不是每次使用新的alertdialog。

到目前为止我做了什么:

\AndroidSDK\platforms\android-23\data\res\layout\alert_dialog.xml中,我看到显示消息的TextView:

<TextView android:id="@+id/message"
    style="?android:attr/textAppearanceMedium"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="5dip" />

\AndroidSDK\platforms\android-23\data\res\values\themes.xml中,我发现textAppearanceMedium属性的值为@style/TextAppearance.Medium

我创建了以下样式,其父级为TextAppearance.AppCompat.Medium。然后将此样式应用于AlertDialog样式的android:textAppearanceMedium属性,如下所示:

<style name="Theme.My" parent="Theme.AppCompat.Light.NoActionBar.FullScreen">
    <item name="android:alertDialogTheme">@style/Theme.My.AlertDialog</item>
</style>

<style name="Theme.My.AlertDialog" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="android:textAppearanceMedium">@style/MyTextAppearanceMedium</item>
</style>

<style name="MyTextAppearanceMedium" parent="TextAppearance.AppCompat.Medium">
    <item name="android:textSize">24sp</item>
</style>

...但字体大小不会改变。怎么了?

我正在使用AppCompat支持lib,min SDK 16,目标SDK 23。

谢谢。

2 个答案:

答案 0 :(得分:3)

AlertDialog使用主题属性?android:attr/textAppearanceMedium"作为对话框内容,直到材质主题。

如果您查看AlertDialog的源代码,则会使用AlertController来管理AlertDialog。在AlertDialog构造函数中,我们有:

 TypedArray a = context.obtainStyledAttributes(null,
             com.android.internal.R.styleable.AlertDialog,
             com.android.internal.R.attr.alertDialogStyle, 0);

     mAlertDialogLayout = a.getResourceId(com.android.internal.R.styleable.AlertDialog_layout,
             com.android.internal.R.layout.alert_dialog);

我们可以看到AlertDialog的布局来自declare-styleable name=AlertDialog中声明的名为“布局”的属性,并在属性{{1}中的主题级别定义}。

知道,看看材料主题中的alertDialogStyle我们得到了这个 alertDialogStyle

Alert.Dialog.Material ,我们得到<item name="alertDialogStyle">@style/AlertDialog.Material</item>

它使用的是 alert_dialog_material ,而不是 alert_dialog

alert_dialog_material 中,我们有相同的<item name="layout">@layout/alert_dialog_material</item>

TextView

但是样式指向的是本地主题,而不是<TextView android:id="@+id/message" style="@style/TextAppearance.Material.Subhead" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingStart="@dimen/alert_dialog_padding_material" android:paddingTop="@dimen/alert_dialog_padding_top_material" android:paddingEnd="@dimen/alert_dialog_padding_material" /> ,这就是为什么你不能像以前那样设置邮件样式。

解决方案1:

我们只能以编程方式执行此操作。使用对话框中的窗口获取?android:attr/textAppearanceMedium并设置所需的外观:

TextView

解决方案2:

为了使其更灵活,我们可以在android.support.v7.app.AlertDialog d = builder.show(); TextView tv = (TextView)d.getWindow().findViewById(android.R.id.message);

中定义属性
attrs.xml

在主题中定义属性:

<resources>
    <attr name="dialogMessageStyle" format="reference"/>
</resources>

使用以下代码在代码中设置:

<style name="MyStyle" ...>
    <item name="dialogMessageStyle">@style/AlertDialogMessageAppearance</item>
</style>

答案 1 :(得分:3)

如果我们遍历android源代码,我们会发现Theme.AppCompat.Light.Dialog.Alert主题继承了alertDialogStyle:

<item name="alertDialogStyle">@style/AlertDialog.AppCompat.Light</item>

通过AlertDialog.AppCompat.Light样式,我们会发现它使用默认布局:

<item name="android:layout">@layout/abc_alert_dialog_material</item>

进一步调查来源,特别是布局@layout/abc_alert_dialog_material,我们将看到ID为TextView的{​​{1}}(这是消息android:id="@android:id/message")使用的样式为TextView

TextAppearance.AppCompat.Subhead

在应用的<TextView android:id="@android:id/message" style="@style/TextAppearance.AppCompat.Subhead" ... /> 文件中覆盖这些样式将更改警报对话框中消息的外观:

values/styles.xml