Applying style to views dynamically in java code

In my answer to Applying style to views dynamically in java code on Jun 25 at 18:51, I thought setting a style to a view dynamically would be as simple as passing the style to the constructor of your view. A couple of minutes ago, I had a notification and a comment (Thank you for it) saying that this does not work. I had a freaking -1 ):

My first solution was to override the constructors and pass the style as a third parameter to the View(android.content.Context, android.util.AttributeSet, int) constructor in this manner:
public StyledButton(Context context) {
    super(context, null, R.style.Button_PrayerTimeButton);
//... whatever
}

public StyledButton(Context context, AttributeSet attrs) {
    super(context, attrs, R.style.Button_PrayerTimeButton);
//... whatever
}

public StyledButton(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, R.style.Button_PrayerTimeButton);
//... whatever
}

So, obviously this did not work although according to the documentation of the third parameter of the constructor:
The default style to apply to this view. If 0, no style will be applied (beyond what is included in the theme). This may either be an attribute resource, whose value will be retrieved from the current theme, or an explicit style resource.
Anyway, now that an explicit style resource is another dead end, I had to find a work around!
And here it is: Instead of supplying a style to the constructor (which again doesn't work for some unknown native reason), you have to supply an attribute and define that attribute in your theme as follows:

styles.xml:


<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <style name="AppBaseTheme" parent="android:Theme.Light">
        <item name="@attr/gangnamStyle">@style/myDefaultStyle</item>
    </style>

    <attr name="gangnamStyle" format="reference" />

    <style name="myDefaultStyle" parent="@android:style/Widget.Button">
        <item name="android:background">#f00</item>
    </style>

</resources>

StyledButton.java:


public class StyledButton extends Button {

 public StyledButton(Context context) {
  super(context, null, R.attr.gangnamStyle);
 }

 public StyledButton(Context context, AttributeSet attrs) {
  super(context, attrs, R.attr.gangnamStyle);
 }

 public StyledButton(Context context, AttributeSet attrs, int defStyle) {
  super(context, null, R.attr.gangnamStyle);
 }
}

Finally, you just have to set the theme of the Activity or Application to your Theme (in this case AppBaseTheme) :
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppBaseTheme" >

And that's it! Enjoy


Click here for Sample Project + Source Code (download)

4 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. hello sherif, I wanted to know from you if there could be any solution where I get color code from web and according I can change color of all my buttons runtime without going to all particular buttons and applying BackGround color, could there be any solution using theme or style? Please share any suggestion you have.

    please also check this question :- http://stackoverflow.com/questions/22529646/android-app-apply-color-theme-dynamically-at-runtime

    ReplyDelete
  3. Really Nice Information,Thank You Very Much For Sharing.
    Web Development Company

    ReplyDelete
  4. Can we use other method for this problem ?
    Example : I have more than one button style. How to use them style (from css) programmatically ?
    Thank you

    ReplyDelete