如何找到窗口小部件的默认样式(即AppCompatEditText)

时间:2017-08-15 15:02:20

标签: android styles themes

  

更新: 正如评论中所指出的,' Widget.AppCompat.EditText'是AppCompatEditText子类的正确父样式。就我而言,真正的问题是我忘记在我们的主题中为控件的默认样式属性赋值,因此我们的控件并没有将任何样式用作默认值。

     

但是,在为子类化标准控件时定义自己的默认样式时,这个问题仍然可以回答如何正确识别哪个样式用作父类。因此,我也改名为。

     

因此,我希望有人可以回答这个问题,因为它可以帮助任何希望做类似事情的人。

我们正在尝试为整个应用中使用的所有AppCompatEditText控件定义一个通用外观。因此,而不是必须手动应用'样式'对于每种用法的属性,我们反而尝试用我们自己的替换默认样式。

更换默认样式实际上很容易。什么不知道我们的风格的父母风格应该设置为什么,所以我们仍然拥有原始风格的所有方面,我们没有明确地用我们的风格覆盖。

挖掘AppCompatEditText的源代码,它显示了要存储在R.attr.editTextStyle中的默认样式,但我不确定现在要查看其中存储的值。

尝试也没有把我们带到任何地方。无论我们到目前为止尝试过什么,我们都完全失去了默认的外观。没有下划线,没有背景,没有填充,没有。只是我们设定的价值,这意味着它没有采用父母风格。

我们尝试了以下但没有成功......

<style name="ZinEditText" parent="android:Widget.EditText">
    <item name="zinTypeface">light</item>
    <item name="android:textSize">@dimen/defaultTextSize</item>
    <item name="android:lineSpacingMultiplier">@dimen/defaultLineSpacing</item>
</style>

<style name="ZinEditText" parent="Widget.AppCompat.EditText">
    <item name="zinTypeface">light</item>
    <item name="android:textSize">@dimen/defaultTextSize</item>
    <item name="android:lineSpacingMultiplier">@dimen/defaultLineSpacing</item>
</style>

<style name="ZinEditText" parent="Base.V7.Widget.AppCompat.EditText">
    <item name="zinTypeface">light</item>
    <item name="android:textSize">@dimen/defaultTextSize</item>
    <item name="android:lineSpacingMultiplier">@dimen/defaultLineSpacing</item>
</style>

<style name="ZinEditText" parent="Widget.Holo.EditText">
    <item name="zinTypeface">light</item>
    <item name="android:textSize">@dimen/defaultTextSize</item>
    <item name="android:lineSpacingMultiplier">@dimen/defaultLineSpacing</item>
</style>

正如我所说,上述情况似乎都没有效果。

那么如何找到实际的父样式呢?

1 个答案:

答案 0 :(得分:3)

要解决当前问题,AppCompatEditText的默认样式为Widget.AppCompat.EditText。你展示的第二个例子是正确的:

<style name="ZinEditText" parent="Widget.AppCompat.EditText">
    ...

这需要设置为应用主题中的editTextStyle

<style name="AppTheme" parent="@style/Theme.AppCompat">
    <item name="editTextStyle">@style/ZinEditText</item>
    ...

据我所知,找到这些默认样式和属性在官方任何地方都没有详细记录。 Styles and Themes的官方文档只是将一个指向框架和支持包的各个R.attr页面,以“发现”可用的内容。但是,对于允许默认样式的大多数View来说,找到这种方法的一般可靠方法是检查源代码。

View子类通常会实现至少三个构造函数:一个只需要Context;需要ContextAttributeSet的人;还有一个ContextAttributeSetint defStyleAttr默认样式属性。这个属性是我们正在寻找的。它通常会有一个合理的名称,例如editTextStyletextViewStylecheckboxStyle等。如果您已经知道名称,则可以跳过检查View类。

在链接其构造函数的View中,此属性通常位于从双参数构造函数调用三参数构造函数中。在AppCompatEditText中,我们可以看到此属性的名称为editTextStyle

public AppCompatEditText(Context context, AttributeSet attrs) {
    this(context, attrs, R.attr.editTextStyle);
}

在我们获得属性的名称之后,我们前往res/values/目录,找到View所在的平台或支持包。默认值将在相关的{{ 1}}文件为您的应用程序的父主题。

对于平台主题,特定主题版本有基础themes.xmlfew others,例如Holo和Material。

对于支持库themes*.xml,这些主题文件将位于特定于包的View目录下,默认属性值可能位于res/values/themes.xml中。

在v7 appcompat中,我们的应用程序的确切父主题可能在v7/appcompat/res/values/themes.xml,但大多数主题只是基本主题的直接别名;即,他们不会覆盖父母的任何属性值。 themes_base.xml的默认值实际上是v7/appcompat/res/values/themes_base.xml。不同主题有单独的条目 - 常规和光 - 但它们都是相同的。

AppCompatEditText

这足以确定哪种样式用作我们的父级,但是如果我们想要查看样式细节,我们可以参考v7/appcompat/res/values/styles.xml,我们在那里找到该样式的父级:

<item name="editTextStyle">@style/Widget.AppCompat.EditText</item>

引导我们v7/appcompat/res/values/styles_base.xml

<style name="Widget.AppCompat.EditText" parent="Base.Widget.AppCompat.EditText"/>