Summary:
This article should be useful to people who want to customize the default UI EditText as well as TextView on the Android platform. Mostly, I mean the Orange skin that appears to be hard to change. No matter how many color properties I attempted, I failed. Then, after inspecting the Android source code, picking apart how they wrote the TextView control (which EditText extends), I realized it was just a skin of NinePatchdrawables set in the background of the underlying View class. I’ll take you through the steps.
Some background on how it works:
First lets look at the art that Android uses, and how they reference it. This provides a better understanding of what we need to do on our own.
Look in the <android_sdk>\platforms\android-x.x\data\res\drawable
directory. In this directory, you will notice this file, edit_text.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_default" /> <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_disabled" /> <item android:state_pressed="true" android:drawable="@drawable/textfield_pressed" /> <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_selected" /> <item android:state_enabled="true" android:drawable="@drawable/textfield_default" /> <item android:state_focused="true" android:drawable="@drawable/textfield_disabled_selected" /> <item android:drawable="@drawable/textfield_disabled" /> </selector>
This is the ColorStateList that is default for the EditText background. This file points to various background resources in each state. So, from inspection, it appears that we need to create NinePatch art for the following drawable files:
textfield_default.9.png, textfield_disabled.9.png, textfield_pressed.9.png, textfield_selected.9.png, textfield_disabled_selected.9.png, etc…
So, this is where and how Android’s default EditText gets the Orange look!
Create your own NinePatch skins:
So change the look to your requirements (using gimp, photoshop, or Android’s recommended Draw9Patch tool), in my case I just did a red version of these files. Place these new png’s in your res/drawable directory. Now they can be referenced by your very own ColorStateList.
Name them .9.png
Create your new ColorStateList
Using the example provided by the default Android edit_text.xml above, create your own version of it, pointing to your own NinePatch files. This file should live in your res/drawable directory also. Now you have a valid ColorStateList visible to styles and widgets.
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_default" /> <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_disabled_red" /> <item android:state_pressed="true" android:drawable="@drawable/textfield_pressed_red" /> <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_selected_red" /> <item android:state_enabled="true" android:drawable="@drawable/textfield_default" /> <item android:state_focused="true" android:drawable="@drawable/textfield_disabled_selected_red" /> <item android:drawable="@drawable/textfield_disabled_red" /> </selector>
Save it as red_edit_text.xml and place in your res/drawable directory.
Point you EditText background to the ColorStateList
In my case, decided to use a theme and style approach to override all EditText boxes in my Application.
From my AndroidManifest.xml application element, set the theme
android:theme="@style/mytheme"
From my theme.xml
<resources> <style name="mytheme" parent="@android:style/Theme" > <item name="android:editTextStyle">@style/red_edittext</item> </style> </resources>
From my styles.xml
<resources>
<style name="red_edittext" parent="@android:style/Widget.EditText">
<item name="android:focusable">true</item>
<item name="android:focusableInTouchMode">true</item>
<item name="android:clickable">true</item>
<item name="android:background">@drawable/red_edit_text</item>
<item name="android:textColor">@color/state_list</item>
<item name="android:gravity">center_vertical</item>
<item name="android:textColorHint">@color/default_text_color</item>
<item name="android:textColorHighlight">@color/transparent_red</item>
</style>
<style name="droiddate_btn" parent="@android:style/Widget.Button">
<item name="android:background">@drawable/btn_default_red</item>
</style>
</resources>
Results:
So now all EditText boxes should have my new red color instead of the default Orange. Although this might not be your end goal, just to change an EditText box from orange to red, it allows you to see how Android NinePatch, ColorStateList , Styles, and Themes can all work together to override and skin any control in Android. It could obviously be much more dramatic than my example below. Good luck, here is the result:
Please feel free to comment,
Marcus Williford
Tags: Android, Android UI, ColorStateList, EditText, Style, Theme