Open a brand-new Android project, look in res/values/, and you will find themes.xml — but no styles.xml, which most older tutorials tell you to edit. If you have ever wondered what the difference is, or where your own styles are supposed to go, this article is for you.
Here is a TextView with its formatting written inline:
<TextView
android:id="@+id/textName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="28sp"
android:textStyle="bold"
android:textColor="#000000"
android:padding="8dp"
android:text="@string/my_name" />Four of those attributes are pure appearance. Add a second heading and you copy them again. Add a third and you copy them again. Then your lecturer asks you to make all headings slightly larger, and you are editing every one by hand.
A style is a named bundle of those attributes, defined once:
<style name="nameStyle">
<item name="android:textSize">28sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">#000000</item>
<item name="android:padding">8dp</item>
</style>Applied with style=:
<TextView
android:id="@+id/textName"
style="@style/nameStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/my_name" />Now 28sp lives in one place. Change it there and every widget using nameStyle updates.
Note that style is written without the android: prefix. It is one of the very few attributes that does not take one, and it catches people out constantly.
Older tutorials say res/values/styles.xml. Newer Android Studio templates do not create that file — they ship res/values/themes.xml instead.
Either file works. Both live in res/values/, and Android merges everything in that folder. The filename is a convention, not a rule.
For a new project, add your style to themes.xml as a sibling of the generated theme:
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- The app theme Android Studio generated for you -->
<style name="Theme.MyApplication" parent="Theme.Material3.DayNight.NoActionBar">
<!-- ... generated theme items ... -->
</style>
<!-- Your own style -->
<style name="nameStyle">
<item name="android:textSize">28sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">#000000</item>
<item name="android:padding">8dp</item>
</style>
</resources>Here is the part that clears up most of the confusion:
A theme and a style are the same <style> element. The only difference is scope — what you apply it to.
style="@style/nameStyle" in the layout.android:theme in the manifest, and cascades down to everything inside it.Same syntax, same file, different scope. That is genuinely all there is to it.
Applying a theme in AndroidManifest.xml:
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.MyApplication">
<activity
android:name=".SettingsActivity"
android:theme="@style/Theme.MyApplication.Dialog" />
</application>An activity-level theme overrides the application-level one for that screen.
This trips up beginners badly, because getting it wrong crashes the app at launch rather than showing a helpful error.
A theme must inherit from a platform theme:
<style name="Theme.MyApplication" parent="Theme.Material3.DayNight.NoActionBar">Without a valid parent, your app is missing the hundreds of attributes Android expects a theme to provide, and it will crash on startup.
A style like nameStyle needs no parent. It is just a bundle of attributes. You can give it one if you want to extend an existing style:
<style name="nameStyle" parent="TextAppearance.AppCompat.Large">
<item name="android:textStyle">bold</item>
</style>A very common question, and the answer is no — it follows the system.
Android Studio generates two theme files:
res/values/themes.xml <- used in light mode
res/values-night/themes.xml <- used in dark modeBoth define a style with the same name. The -night suffix is a resource qualifier, like values-my for Malay or drawable-hdpi for screen density. At runtime Android picks the folder matching the device configuration, so @style/Theme.MyApplication resolves differently depending on the phone's dark mode setting. The manifest line never changes.
The reason people think it is fixed to light: the emulator defaults to light mode, so a new project looks light and stays light through an entire lab session. Flip the emulator to dark (Settings → Display → Dark theme) and the app changes with no code edit at all.
To force one mode regardless of the system, you must do it in code — the manifest cannot express this:
// Before setContentView(), or in Application.onCreate()
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); // always light
// MODE_NIGHT_YES — always dark
// MODE_NIGHT_FOLLOW_SYSTEM — the defaultStyles hold appearance, not identity or position. Do not put these in a style:
android:id — every widget needs its ownandroid:layout_width / android:layout_height — technically possible, but confusing, since layout attributes belong to the parentIf an attribute is set in both the style and the layout, the layout wins. That makes it easy to apply a style and then override one detail on a single widget.
style= (no android: prefix)android:theme in the manifestres/values/ — themes.xml in new projects, styles.xml in older onesparent; plain styles usually do notvalues-night/ provides the dark-mode variant automatically