5

Questo è un "bug" che ho scoperto mentre lavoravo su un'app reale, ma ho creato un progetto vuoto per riprodurlo.La classe figlio di EditText è diversa dal normale EditText su Android 4

ho il seguente schema:

<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> 

La classe MyEditText si presenta così:

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); 
    } 


} 

Il mio file styles.xml è vuoto tranne che per il tema

<resources> 

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

</resources> 

mi si aspetterebbe il MyEditText sembra il normale EditText e lo fa su Android 5.0, ma non su Android 2.3.7, Android 4.1.3 o Android 4.4.4.

Per questi versioni di Android i EditText s si differenziano per il colore, quella normale ha una sottolineatura ciano quando si è concentrato, quello personalizzato ha una sottolineatura nera:

enter image description here

enter image description here

perché è questo accadendo e come posso prevenirlo?

EDIT/UPDATE:

Google seems to have adressed this nella libreria di supporto, introducendo, tra l'altro, una classe AppCompatEditText.

risposta

6

perché sta succedendo questo

Poiché si utilizza AppCompat. Citando the blog post on the subject:

D: Perché la mia EditText (o altro widget elencati sopra) non essere colorato in modo corretto sul dispositivo di pre-Lollipop?

A: La sfumatura del widget in AppCompat funziona intercettando qualsiasi rigonfiamento del layout e inserendo al suo posto una versione speciale del widget che riconosce la tinta. Per molte persone questo funziona bene, ma posso pensare a un paio di scenari in cui questo non funzionerà, tra cui:

  • avete la propria versione personalizzata del widget (vale a dire che hai esteso EditText)
  • Si sta creando il EditText senza un LayoutInflater (ad esempio, chiamando new EditText()).

Quindi, il comportamento è previsto. Il backport di AppCompat fornisce alcuni backport leggeri di colorazione, ma non gestirà tutti i casi.

come posso impedirlo?

a braccio, o:

  • Non creare una sottoclasse di EditText o

  • Quando si esegue l'AppCompat, cercare la tinta e capire come applicare da soli , forse esaminando il codice sorgente AppCompat (supponendo che sia disponibile - Non l'ho cercato), oppure

  • Non utilizzare AppCompat e vedere se la tinta funziona come atteso utilizzando Theme.Material sui dispositivi Android 5.0+

E 'possibile che un futuro AppCompat potrebbe fornire una sorta di sistema per sottoclassi di partecipare al processo di colorazione. E potrebbero esserci altre soluzioni oltre a queste: ecco cosa viene in mente.

+0

Wow, hai già preparato questa risposta? :) Grazie mille! – FWeigl

+0

@ Ascorbin: "Wow, hai già preparato questa risposta?" - beh, è ​​una mezza citazione, che risparmia sulla digitazione. :-) Avrò bisogno di guardare la mia seconda opzione io stesso ad un certo punto, in quanto ho [una sottoclasse di 'EditText'] (https://github.com/commonsguy/cwac-richedit) che soffrirà dello stesso problema. – CommonsWare

5

In realtà la conclusione raggiunta in questa risposta accettata qui non è completamente vera (più). È DOVREBBE utilizzare AppCompat, ma è sufficiente rendersi conto che AppCompat sostituirà il tuo EditText con AppCompatEditText durante l'inflazione del layout. Lo stesso processo accade anche ad alcuni altri elementi dell'interfaccia utente, come Switch, CheckBoxes, ecc. Google ha fatto questo in modo che possano spingere il design del materiale look-n-feel così lontano e in largo con modifiche al codice minime da parte degli utenti.

Se si desidera sottoclasse EditText, è necessario sottoclasse AppCompatEditText (android.support.v7.widget.AppCompatEditText).