140

Let's say I want all the TextView instances in my app to have textColor="#ffffff". Is there a way to set that in one place instead of setting it for each TextView?

Chris Stillwell
  • 10,266
  • 10
  • 67
  • 77
Emanuil Rusev
  • 34,563
  • 55
  • 137
  • 201

4 Answers4

283

Actually, you can set a default style for TextViews (and most other built-in widgets) without needing to do a custom java class or setting the style individually.

If you take a look in themes.xml in the Android source, you will see a bunch of attributes for the default style for various widgets. The key is the textViewStyle (or editTextStyle, etc.) attribute which you override in your custom theme. You can override these in the following way:

Create a styles.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyTheme" parent="android:Theme">
    <item name="android:textViewStyle">@style/MyTextViewStyle</item>
</style>

<style name="MyTextViewStyle" parent="android:Widget.TextView">
    <item name="android:textColor">#F00</item>
    <item name="android:textStyle">bold</item>
</style>
</resources>

Then just apply that theme to your application in AndroidManifest.xml:

<application […] android:theme="@style/MyTheme">…

And all your text views will default to the style defined in MyTextViewStyle (in this instance, bold and red)!

This was tested on devices from API level 4 onward and seems to work great.

Steve Pomeroy
  • 10,071
  • 6
  • 34
  • 37
  • @Steve, if I include the item `@style/MyTextViewStyle` in style MyTheme and then apply the style to my application, all my `TextView`s will be shown according to the style (even the name of the application in the action bar). How to fix the matter with the action bar? I want it to have the default appearance. [Github](https://github.com/Red-Planet/Test_Auth_with_Google_Acc) – Maksim Dmitriev Dec 25 '12 at 11:02
  • @Steve, How to apply both(action bar and widget) theme on application – Pratik Butani Jun 29 '13 at 07:51
  • I'm not sure about how to differentiate the ActionBar from other things. You may be able to find wherever your ActionBar style is set and then put `@style/MyTextViewStyle` there too, just pointing to the ActionBar default (or something similar) – Steve Pomeroy Dec 10 '13 at 21:09
  • @StevePomeroy this does not work for me.. can you provide some Support. My Style for the TextViews stays the same. Are there a Minimum of items i Need to set or are there some items i'm not allowed to set? – Mike Dec 17 '14 at 21:56
  • what if I have already defined a style for another widget in my `application` tag? the `style` attribute doesn't seems to accept multiple values – jack_the_beast Nov 13 '15 at 14:37
  • Wouldn't this break the style of the TextView, because it should use `parent="android:Widget.Material.TextView"` when possible ? – android developer May 19 '18 at 10:24
  • Does this affect EditText too? – android developer Jan 13 '19 at 12:52
54

There are two ways to do so:

1. Using styles

You can define your own styles by creating XML files on the res/values directory. So, let's suppose you want to have red and bold text, then you create a file with this content:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="MyRedTheme" parent="android:Theme.Light">
    <item name="android:textAppearance">@style/MyRedTextAppearance</item>
  </style>
  <style name="MyRedTextAppearance" parent="@android:style/TextAppearance">
    <item name="android:textColor">#F00</item>
    <item name="android:textStyle">bold</item>
  </style>
</resources>

You can name it like you want, for instance res/values/red.xml. Then, the only thing you have to do is using that view in the widgets that you want, for instance:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView
    style="@style/MyRedTheme"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="This is red, isn't it?"
    />
</LinearLayout>

For further reference, you can read this article: Understanding Android Themes and Styles

2. Using custom classes

This is another possible way to achieve this, and it would be to provide your own TextView that set the text color always to whatever you want; for instance:

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.widget.TextView;
public class RedTextView extends TextView{
    public RedTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setTextColor(Color.RED);
    }
}

Then, you just have to treat it as a normal TextView in your XML file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<org.example.RedTextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="This is red, isn't it?"
    />
</LinearLayout>

Whether you use one or another choice depends on your needs. If the only thing you want to do is modifying the appearance, then the best approach is the first. On the other hand, if you want to change the appearance and add some new functionality to your widgets, the second one is the way to go.

Cristian
  • 198,401
  • 62
  • 356
  • 264
  • using custom classes should be preferred as that is cleaner approach and helps keep xml file light weight. – Amit Kumar Feb 13 '16 at 07:39
  • 1
    @AmitKumar No they should not! In this particular case this would mean to use a separate custom class for each different attribute value. This produces a lot of bloat code and makes the actual layout not readable any more (you will have to visit each class to see what it is doing instead of just reading few xml lines). Custom classes should only be used if you modify the behavior, but not if the only change is the look of the view. – Andre Nov 01 '18 at 14:02
  • Is it not possible to set the style of a custom view from xml? Why can we not use it in the `custom_view_layout.xml` file that is used to inflate a custom class? – lucidbrot Jan 07 '20 at 20:54
5

For default text color in TextView, set android:textColorTertiary in your theme to desired color:

<item name="android:textColorTertiary">@color/your_text_color</item>

Many other Android control's colors can be controlled using framework attributes, or support library attributes if you use support library.

For a list of attributes you can set, check out Android source code of styles.xml and themes.xml, or this very helpful gist by Dan Lew, try changing each value and see what they change on screen.

hidro
  • 12,333
  • 6
  • 53
  • 53
  • Thank you, man! I spent a bunch of time figuring out why textColorPrimary does not work. – pratt Jun 09 '17 at 12:40
3

Define a style and use it on each widget, define a theme that overrides the android default for that widget, or define a string resource and reference it in each widget

TWH
  • 71
  • 3