Child class of EditText looks different than normal EditText on Android 4
Asked Answered
B

2

5

This is a 'bug' that I discovered while working on a real app, but I created a blank project to reproduce it.

I have the following layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:id="@+id/root"
    android:orientation="vertical"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <com.example.test.testapp.MyEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />


</LinearLayout>

The class MyEditText looks like this:

public class MyEditText extends EditText {

    public MyEditText(Context context){
        super(context);
    }

    public MyEditText(Context context, AttributeSet attrs){
        super(context, attrs);
    }


    public MyEditText(Context context, AttributeSet attrs, int defStyle){
        super(context, attrs, defStyle);
    }


}

My styles.xml file is empty except for the Theme

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

</resources>

I would expect the MyEditText to look like the normal EditText and it does on Android 5.0, but not on Android 2.3.7, Android 4.1.3 or Android 4.4.4.

On those Android versions the EditTexts differ in color, the normal one has a cyan underline when focused, the custom one has a black underline:

enter image description here

enter image description here

Why is this happening and how can I prevent it?

EDIT / UPDATE:

Google seems to have adressed this in the support library by introducing, amongst others, an AppCompatEditText class.

Bakelite answered 6/2, 2015 at 14:48 Comment(0)
H
6

Why is this happening

Because you are using AppCompat. Quoting the blog post on the subject:

Q: Why is my EditText (or other widget listed above) not being tinted correctly on my pre-Lollipop device?

A: The widget tinting in AppCompat works by intercepting any layout inflation and inserting a special tint-aware version of the widget in its place. For most people this will work fine, but I can think of a few scenarios where this won’t work, including:

  • You have your own custom version of the widget (i.e. you’ve extended EditText)
  • You are creating the EditText without a LayoutInflater (i.e., calling new EditText()).

So, the behavior is expected. The AppCompat backport provides some lightweight backporting of tinting, but it's not going to handle all cases.

how can I prevent it?

Off the cuff, either:

  • Do not create a subclass of EditText, or

  • When running on AppCompat, look up the tint and figure out how to apply it yourself, perhaps by examining the AppCompat source code (assuming it's available -- I haven't looked for it), or

  • Do not use AppCompat, and see if tinting works as expected using Theme.Material on Android 5.0+ devices

It's possible that a future AppCompat could provide some sort of system for subclasses to participate in the tinting process. And there may be other solutions than these -- these are what come to mind.

Hyperform answered 6/2, 2015 at 14:52 Comment(2)
Wow, did you have this answer already prepared? :) Thanks a bunch!Bakelite
@Ascorbin: "Wow, did you have this answer already prepared?" -- well, it's half a quote, which saves on typing. :-) I'll need to look at my second option myself at some point, as I have a subclass of EditText that will suffer from the same problem.Hyperform
U
5

Actually the conclusion reached in this accepted answer here is not entirely true (anymore). You SHOULD use AppCompat, but just need to realise that AppCompat will substitute your EditText with AppCompatEditText during layout inflation. The same process happens to a few other UI elements too, like Switch, CheckBoxes, etc. Google did this so that they can push Material design look-n-feel as far and wide with minimal code changes from the users.

If you want to subclass EditText, you should subclass AppCompatEditText (android.support.v7.widget.AppCompatEditText).

Unprofitable answered 8/10, 2015 at 5:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.