I am using appcompat v7 to get the look consistent on Android 5 and less. It works rather well. However I cannot figure out how to change the bottom line color and the accent color for EditTexts. Is it possible?
I have tried to define a custom android:editTextStyle
(cf. below) but I only succeeded to change the full background color or text color but not the bottom line nor the accent color. Is there a specific property value to use? do I have to use a custom drawable image through the android:background
property? is it not possible to specify a color in hexa?
<style name="Theme.App.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:editTextStyle">@style/Widget.App.EditText</item>
</style>
<style name="Widget.App.EditText" parent="Widget.AppCompat.EditText">
???
</style>
According to android API 21 sources, EditTexts with material design seem to use colorControlActivated
and colorControlNormal
. Therefore, I have tried to override these properties in the previous style definition but it has no effect. Probably appcompat does not use it. Unfortunately, I cannot find the sources for the last version of appcompat with material design.
AppCompatEditText
, apparently.
Finally, I have found a solution. It simply consists of overriding the value for colorControlActivated
, colorControlHighlight
and colorControlNormal
in your app theme definition and not your edittext style. Then, think to use this theme for whatever activity you desire. Below is an example:
<style name="Theme.App.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorControlNormal">#c5c5c5</item>
<item name="colorControlActivated">@color/accent</item>
<item name="colorControlHighlight">@color/accent</item>
</style>
I felt like this needed an answer in case somebody wanted to change just a single edittext. I do it like this:
editText.getBackground().mutate().setColorFilter(ContextCompat.getColor(context, R.color.your_color), PorterDuff.Mode.SRC_ATOP);
While Laurents solution is correct, it comes with some drawbacks as described in the comments since not only the bottom line of the EditText
gets tinted but the Back Button of the Toolbar
, CheckBoxes
etc. as well.
Luckily v22.1
of appcompat-v7
introduced some new possibilities. Now it's possible to assign a specific theme only to one view. Straight from the Changelog:
Deprecated use of app:theme for styling Toolbar. You can now use android:theme for toolbars on all API level 7 and higher devices and android:theme support for all widgets on API level 11 and higher devices.
So instead of setting the desired color in a global theme, we create a new one and assign it only to the EditText
.
Example:
<style name="MyEditTextTheme">
<!-- Used for the bottom line when not selected / focused -->
<item name="colorControlNormal">#9e9e9e</item>
<!-- colorControlActivated & colorControlHighlight use the colorAccent color by default -->
</style>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/MyEditTextTheme"/>
colorControlNormal
without the android prefix uses the appcompat method to tint widgets while with the prefix it fallsback to the system method and this is only available in API 21+ devices.
22.2.0
version of AppCompat but this trick is not working :(
This can be changed in XML by using:
For Reference API >= 21 compatibility use:
android:backgroundTint="@color/blue"
For backward API < 21 compatibility use:
app:backgroundTint="@color/blue"
backgroundTint="@color/blue"
instead of android:backgroundTint="@color/blue"
for backward compatible support
android:backgroundTint="@color/blue"
, use app:backgroundTint="@color/blue"
to support pre-Lollipop devices, thanks for your comment !
tools:ignore="MissingPrefix"
if a red underline pop under app:backgroundTint="<your color>"
Here is the solution for API < 21 and above
Drawable drawable = yourEditText.getBackground(); // get current EditText drawable
drawable.setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_ATOP); // change the drawable color
if(Build.VERSION.SDK_INT > 16) {
yourEditText.setBackground(drawable); // set the new drawable to EditText
}else{
yourEditText.setBackgroundDrawable(drawable); // use setBackgroundDrawable because setBackground required API 16
}
https://i.stack.imgur.com/wu1yD.png
Hope it help
24.2.1
, 25.1.1
, 25.2.0
for device < 21 and > 21 and it still working. Please check this simple demo drive.google.com/file/d/0B_poNaia6t8kSzU3bDFVazRSSDA/…. I don't know why this code not work for you so please let me know. thank you
The accepted answer is a bit more per style basis thing, but the most efficient thing to do is to add the colorAccent attribute in your AppTheme style like this:
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorAccent">@color/colorAccent</item>
<item name="android:editTextStyle">@style/EditTextStyle</item>
</style>
<style name="EditTextStyle" parent="Widget.AppCompat.EditText"/>
The colorAccent attribute is used for widget tinting throughout the app and thus should be used for consistency
name="android:colorAccent"
mistakenly
If you are using appcompat-v7:22.1.0+
you can use the DrawableCompat to tint your widgets
public static void tintWidget(View view, int color) {
Drawable wrappedDrawable = DrawableCompat.wrap(view.getBackground());
DrawableCompat.setTint(wrappedDrawable.mutate(), getResources().getColor(color));
view.setBackgroundDrawable(wrappedDrawable);
}
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="colorControlNormal">@color/colorAccent</item>
<item name="colorControlActivated">@color/colorAccent</item>
<item name="colorControlHighlight">@color/colorAccent</item>
</style>
Use:
<EditText
app:backgroundTint="@color/blue"/>
This will support pre-Lollipop devices not only +21
android:theme="@style/Theme.App.Base
. This will ensure the style won't also affect other views in your layouts that you don't want to change.AppCompatActivity
. It will not work if it inherits fromActivity
.