javaandroidandroid-custom-viewandroid-stylesandroid-custom-attributes

Apply built-in Android widget styles in a custom view


I have read and understood https://stackoverflow.com/a/5052401/305532, however what I want is not to generally style and override individual widget styles, but styles that are part of sub-widgets.

Say, I have a compound RelativeLayout that consists of a standard EditText and a standard Button. I could override android:buttonStyle to style this Button, but what I really want is

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

where the CustomStyle could derive from android:style/Widget.Button, but would be changeable for each instance of my.custom.Widget because of pkg:buttonStyle.

The only alternative I know is to add all styleable attributes individually into my attrs.xml (with the usual conflicts in case two or more of your sub-widgets need the same attribute, but with different values) and then manually copying / setting all these attributes in my.custom.Widget's constructor / init method.

Is there a way to achieve this?


Solution

  • Unfortunately, this doesn't seem to be possible. The only example I could find that does something similar is ActionBar: you can pass in styles for the title, subtitle, and progress indicators. Looking at the source for ActionBarView, the title and subtitle TextViews' styles are applied with setTextAppearance(). The ProgressBar class has an extra constructor that accepts a fourth parameter for the style. Since most View classes don't have this extra constructor, passing in a style to them is not possible. However, there are a few alternatives:

    1. Pass a layout for the subview instead of a style and inflate it in your widget.
    2. If the subview is a child of TextView (as Button and EditText are), use setTextAppearance() for the passed style. This will apply a good bit of the styling for text. If you want to allow the user to apply other styles like background or padding, you will still need to add custom attributes for each of those as well. If you're making a compound widget there's a good chance that the user won't need to apply every possible style to the subviews, so only exposing a subset will probably suffice.
    3. Add a theme-wide style, as you already mentioned.