我正在继承Android的内置小部件,如TextView,CheckBox和RadioButton,并添加了一些额外的属性/属性。我还想为每个子类指定一个默认样式,这样我就可以在使用时预先配置它们。
我的问题是我如何定义自己的默认样式,但是要将该样式与基类的默认样式合并,而不是直接替换它?
我一直在遵循使用以下推荐技术主题化应用程序自定义小部件的最佳实践。
对于名为MyWidget的View子类,请考虑以下内容:
public class MyWidget extends View
{
public MyWidget(Context context)
{
this(context, null);
}
public MyWidget(Context context, AttributeSet attrs)
{
super(context, attrs, R.attr.myWidgetStyle);
TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.MyWidget, R.attr.myWidgetStyle, 0);
// Only need to read custom attributes here
// Others are handled in the base class
styledAttrs.recycle();
}
}
<!-- Attribute to hold the default style -->
<attr name="myWidgetStyle" format="reference" />
<!-- Assigning attributes to controls -->
<declare-styleable name="MyWidget">
<attr name="isRealTime" format="boolean" />
</declare-styleable>
<style name="MyTheme">
<!-- Store default style in the style-reference attributes -->
<item name="myWidgetStyle">@style/MyWidget</item>
</style>
<style name="MyWidget">
<item name="background">@color/someColorResource</item>
<item name="isRealTime">true</item>
</style>
一切都按预期工作,我的控件选择了指定的默认样式。
当代替子类化View而不是子类化RadioButton时,问题出现了。使用它作为一个例子,因为我在构造函数中调用'super'手动指定defStyleAttr,我的样式完全取代了默认样式,我失去了RadioButton的默认外观并且没有出现点,只是文本。
如果我没有将我的defStyleAttr传递给'super'并且仅在调用obtainStyledAttributes时使用它(以处理我自定义的那些),那么以该样式设置的任何非自定义属性(如margin,background,buttonTint)因为通常处理它们的基类不再知道我的默认样式,所以它不会被应用,所以它会回退到基类的默认外观。
解决这个问题的最简单方法当然是通过我的样式的'parent'属性将我的默认样式基于RadioButton现有的默认样式,然后当我的样式成为新的默认样式时,它是两个混合了我的值的样式优先。
问题是我不知道基本控件的默认样式是什么(本例中的RadioButton),因为我不知道他们用它来保存它(它是假设的是radioButtonStyle但是没有用),即使我确实知道属性,这也不是我需要的。我需要它所指出的风格。 (我也试过了?someAttr和?attr / someAttr',但都没有奏效。)
希望你能够遵循这一点。更好的是,希望你有答案!
答案 0 :(得分:0)
问题在于我不知道基本控件的默认样式是什么
AppCompat提供的小部件及其默认样式遵循命名约定。示例:AppCompatEditText
默认样式由?editTextStyle
主题属性控制,默认情况下指向@style/Widget.AppCompat.EditText
。
大多数情况下,您可以猜出正确的名称(IDE会帮助您),但如果您正在寻找确定样式的“正确”方法,请按以下步骤操作:
AppCompatEditText
。R.attr.editTextStyle
。values.xml
,找到Theme.AppCompat
定义。它将包含所有默认样式。查找theme属性引用的具体样式。 看起来像这样:
<style name="Theme.AppCompat" parent="@style/Base.Theme.AppCompat">
<item name="editTextStyle">@style/Widget.AppCompat.EditText</item>
<!-- Other styles... -->
</style>
...作为您找到的风格的延伸。
<style name="Widget.VeryCustomEditText" parent="@style/Widget.AppCompat.EditText">
如果您直接使用EditText
等扩展平台小部件,则会有所不同。我会在必要时扩大答案。