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



UPDATE:正如注释中指出的,'Widget.AppCompat.EditText'是AppCompatEditText子类的正确父样式。 就我而言,真正的问题是我忘记在主题中为控件的默认样式属性分配值,因此我们的控件没有任何样式可用作默认值。

但是,这个问题仍然可以使用一个答案,即在子类化标准控件时定义自己的默认样式时,如何正确标识要用作父样式的样式。因此,我也重命名了它的标题。

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

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

替换默认样式实际上是简单的部分。 不知道的是知道我们样式的父样式应该设置为什么,这样我们仍然拥有原始样式的所有方面,我们没有明确地用我们中的样式覆盖这些方面。

挖掘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>

正如我所说,以上似乎都不起作用。

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

为了解决眼前的问题,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>
...

据我所知,找到这些默认样式和属性在任何地方都没有很好的记录。样式和主题的官方文档只是将人们引导到框架和支持包的各个R.attr页面,以"发现"可用的内容。但是,对于大多数允许默认样式的View,通常可靠的方法是检查源代码。

一个View子类通常会实现至少三个构造函数:一个只接受Context;一个接受ContextAttributeSet;另一个接受ContextAttributeSetdefStyleAttrint,一个默认的样式属性。此属性就是我们正在寻找的。它通常有一个合理的名称,如editTextStyletextViewStylecheckboxStyle等。如果您已经知道该名称,则可以跳过检查View类以获取它。

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

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

获得属性的名称后,我们转到View所在的平台或支持包的res/values/目录。默认值将位于应用父主题的相关themes*.xml文件中。

对于平台主题,有一个基本themes.xml,还有一些其他主题版本,例如Holo和Material。

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

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

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

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

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

这导致我们v7/appcompat/res/values/styles_base.xml

<style name="Base.Widget.AppCompat.EditText" parent="Base.V7.Widget.AppCompat.EditText" />
<style name="Base.V7.Widget.AppCompat.EditText" parent="android:Widget.EditText">
<item name="android:background">?attr/editTextBackground</item>
<item name="android:textColor">?attr/editTextColor</item>
<item name="android:textAppearance">?android:attr/textAppearanceMediumInverse</item>
</style>

相关内容

  • 没有找到相关文章

最新更新