在自定义视图中应用内置Android小部件样式

时间:2013-06-18 09:25:00

标签: java android android-custom-view android-styles android-custom-attributes

我已阅读并理解https://stackoverflow.com/a/5052401/305532,但我想要的不是通常设计和覆盖单个窗口小部件样式,而是属于子窗口小部件的样式。

说,我有一个由标准RelativeLayout和标准EditText组成的复合Button。我可以覆盖android:buttonStyle来设置此Button的样式,但我真正想要的是

<my.custom.Widget
  ...
  pkg:buttonStyle="@style/CustomStyle" />

CustomStyle可以从android:style/Widget.Button派生,但由于my.custom.Widgetpkg:buttonStyle的每个实例都可以更改。

我知道的唯一选择是将所有可设置属性单独添加到我的attrs.xml中(如果两个或更多个子窗口小部件需要相同的属性,但具有不同的值,则通常存在冲突)然后手动在my.custom.Widget的构造函数/ init方法中复制/设置所有这些属性。

有没有办法实现这个目标?

2 个答案:

答案 0 :(得分:2)

不幸的是,这似乎不可能。我能找到的唯一一个类似的例子是ActionBar:你可以为标题,副标题和进度指示器传递样式。查看ActionBarView的来源,标题和副标题TextView s'样式将应用setTextAppearance()ProgressBar class有一个额外的构造函数,它接受样式的第四个参数。由于大多数View类没有这个额外的构造函数,因此无法将样式传递给它们。但是,有一些选择:

  1. 传递子视图的布局而不是样式,并在窗口小部件中对其进行充气。
  2. 如果子视图是TextView的子项(ButtonEditText为),请使用setTextAppearance()作为传递的样式。这将为文本应用一些好的样式。如果要允许用户应用其他样式(如背景或填充),您仍需要为每个样式添加自定义属性。如果您正在制作复合小部件,那么用户很可能不需要将所有可能的样式应用于子视图,因此仅暴露子集可能就足够了。
  3. 添加主题范围的样式,如您所述。

答案 1 :(得分:1)

在自定义视图中使用内置窗口小部件样式

如果您创建的自定义视图是Android窗口小部件的子类,并希望使用内置的Android窗口小部件样式设置样式,则必须实现以下结构。


更改自定义View以从Android Widget样式继承其属性

CustomTextView.java

public class CustomTextView extends TextView {
    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray styledAttrs = context.obtainStyledAttributes(attrs,
                R.styleable.CustomTextView, R.attr.customImageButtonStyle, 0);
        String fontName = styledAttrs.getString(
                R.styleable.CustomTextView_customTypeface);
        styledAttrs.recycle();

        // Use custom attribute to do something...
    }
}

defStyleAttr的{​​{1}}参数是指定要继承的样式的引用的位置。在此示例中,您使用Context#obtainStyledAttributes()。您可以在R.attr.customImageButtonStylethemes.xml中定义这些资源。

的themes.xml

styles.xml

styles.xml

<resources>
    <style name="AppTheme">
        <!--Define a theme-wide customTextViewStyle -->
        <item name="customTextViewStyle">@style/Widget.TextView</item>
    </style>
</resources>

attrs.xml

<resources>
    <style name="Widget.TextView"
        parent="@android:style/Widget.TextView">
        <item name="customTypeface">custom_font_typeface</item>
    </style>
</resources>

*的 activity_layout *

<resources>
    <declare-styleable name="CustomTextView">
        <attr name="customTypeface" format="string" />
    </declare-styleable>
    <declare-styleable name="CustomTheme">
        <attr name="customTextViewStyle" format="reference"/>
    </declare-styleable>
</resources>

<com.packagename.ui.view.CustomTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Bacon ipsum" /> 不再要求您定义样式或CustomTextView属性,它已在customTypeface中的主题范围customTextViewStyle中定义。