Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I apply a style programmatically?

Tags:

android

I have a styles called Red and Green and I have an if statment to find out which to apply, but I don't know the code to actually apply a style from the java.

like image 594
Somk Avatar asked Feb 19 '11 15:02

Somk


4 Answers

There is no one line solution to this problem, but this worked for my use case. The problem is, the 'View(context, attrs, defStyle)' constructor does not refer to an actual style, it wants an attribute. So, we will:

  1. Define an attribute
  2. Create a style that you want to use
  3. Apply a style for that attribute on our theme
  4. Create new instances of our view with that attribute

In 'res/values/attrs.xml', define a new attribute:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="customTextViewStyle" format="reference"/>
    ...
</resources>    

In res/values/styles.xml' I'm going to create the style I want to use on my custom TextView

<style name="CustomTextView">
    <item name="android:textSize">18sp</item>
    <item name="android:textColor">@color/white</item>
    <item name="android:paddingLeft">14dp</item>
</style>

In 'res/values/themes.xml' or 'res/values/styles.xml', modify the theme for your application / activity and add the following style:

<resources>
    <style name="AppBaseTheme" parent="android:Theme.Light">
        <item name="customTextViewStyle">@style/CustomTextView</item>
    </style>
    ... 
</resources>

Finally, in your custom TextView, you can now use the constructor with the attribute and it will receive your style. Here, instead of always

public class CustomTextView extends TextView {

    public CustomTextView(Context context, int styleAttribute) {
        super(context, null, styleAttribute);
    }

    // You could also just apply your default style if none is given
    public CustomTextView(Context context) {
        super(context, null, R.attr.customTextViewStyle);
    }
}

With all of these components, you can now do an if/else statement to generate new views at runtime with the style you prefer

CustomTextView ctv;
if(useCustomStyles == true){
    ctv = new CustomTextView(context, R.attr.customTextViewStyle);
}else{
    ctv = new CustomTextView(context, R.attr.someOtherStyle);
}

It's worth noting that I repeatedly used customTextView in different variants and different places, but it is in no way required that the name of the view match the style or the attribute or anything. Also, this technique should work with any custom view, not just TextViews.

like image 50
Kevin Grant Avatar answered Nov 14 '22 21:11

Kevin Grant


It is possible to apply styles programatically to TextViews using setTextAppearance(context, resid) method. (The resId of the style can be found in R.style.YourStyleName)

like image 41
Shahul3D Avatar answered Nov 14 '22 21:11

Shahul3D


I found out this is only able to be done when creating an View from inside the Java. If it is defined in the XML before hand you cannot dynamically change the style.

like image 7
Somk Avatar answered Nov 14 '22 22:11

Somk


You can use the brand new Paris library to apply styles programmatically:

Paris.style(yourView).apply(condition ? R.style.Green : R.style.Red);

The only caveat is that not all attributes are supported (but many are and support can be added fairly easily by contributing to the library).

  • List of currently supported attributes
  • Installation instructions

Disclaimer: I'm the original author of the library.

like image 4
Nathanael Avatar answered Nov 14 '22 21:11

Nathanael