Style inheritance of extended Widget

2019-04-08 15:00发布

问题:

In my project (Target API 21 with AppCompat support), I need to extend the EditText class. My problem is MyEditText class does not inherit EditText style customized with:

<style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar" >
    <item name="colorPrimary">@color/primary</item>
    <item name="colorControlNormal">@color/grey_light</item>
    <item name="colorControlActivated">@color/primary</item>
    <item name="colorControlHighlight">@color/primary</item>
</style>

with @color/primary green


Screenshot:

  • line 1: EditText focused
  • line 2: EditText not focused (enabled)
  • line 3: MyEditText not focused (enabled)

My question is: How can I inherit default EditText style in MyEditText ?

回答1:

Has a way very, very, very easy.

Instead of inheriting from android.widget.EditText your Custom EditText, inherit this class and see if it works:

android.support.v7.internal.widget.TintEditText

Link to the class: TintEditText.java

Read the Javadoc of the class, he says:

/**
 * An tint aware {@link android.widget.EditText}.
 * <p>
 * This will automatically be used when you use {@link android.widget.EditText} in your
 * layouts. You should only need to manually use this class when writing custom views.
 */

In the stretch of this page (Using Support Library APIs) has a caution which is: When using classes from the Support Library, be certain you import the class from the appropriate package. For example, when applying the ActionBar class:

  • android.support.v7.app.ActionBar when using the Support Library.
  • android.app.ActionBar when developing only for API level 11 or higher.

I interpreted this, that is, if you are using a support library, always try to import or inherit the appropriate package. (Nothing less than that is written lol.: D)



回答2:

You can work around it using styles

In your Theme

<style name="AppTheme.BaseNoActionBar" parent="Theme.AppCompat.Light">
    <item name="android:editTextStyle">@style/Widget.EditText</item>
</style>


<!-- EditText style -->
<style name="Widget.EditText" parent="Widget.AppCompat.EditText">
    <item name="android:textCursorDrawable">@drawable/cursor_gray</item>
    <item name="android:background">@drawable/underline_gray</item>
</style>

then define the cursor

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <size android:width="1dp" />
    <solid android:color="@color/lightGrayLabel"  />
</shape>

and the drawable according to this hack https://stackoverflow.com/a/20891131

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:top="-6dp" android:left="-6dp" android:right="-6dp">
        <shape android:shape="rectangle">
            <solid android:color="@android:color/transparent"/>
            <stroke android:color="@color/lightGrayLabel" android:width="3dp"/>
        </shape>
    </item>
</layer-list>

I have also tried using selector as the "background" field, but it didn't work with either "android:state_selected" or "android:state_activated"

Here's a little example