2015-06-15 32 views
15

Sto utilizzando TextInputLayout da Android Design Library per mostrare l'etichetta su EditText.TextInputLayout hint overlap issue

Il problema è quando avvio un'attività con il testo di suggerimento EditText (etichetta) si sovrappone al testo effettivo (per un secondo) e solo dopo ritorna al suo posto (all'inizio di EditText).

Per illustrare questo problema ho registrato un breve video di esempio: https://youtu.be/gy0CzcYggxU

Ecco il mio activity.xml:

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_margin="16dp" 
    android:orientation="vertical"> 

<android.support.design.widget.TextInputLayout 
    android:id="@+id/firstNameTextInputLayout" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_marginTop="8dp"> 

    <EditText 
     android:id="@+id/firstNameEditText" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:hint="@string/first_name" 
     android:inputType="textCapWords" 
     android:textColor="@color/textPrimary" 
     android:textColorHint="@color/textSecondary" 
     android:textSize="16sp" 
     android:theme="@style/CustomEditText"/> 
</android.support.design.widget.TextInputLayout> 


<android.support.design.widget.TextInputLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_marginTop="24dp"> 

    <EditText 
     android:id="@+id/lastNameEditText" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:hint="@string/last_name" 
     android:inputType="textCapWords" 
     android:textColor="@color/textPrimary" 
     android:textColorHint="@color/textSecondary" 
     android:textSize="16sp" 
     android:theme="@style/CustomEditText"/> 
</android.support.design.widget.TextInputLayout> 

+0

Penso che questo accada quando torni ad Attività che ha quei valori con valori editi? – Herry

+0

@Herry Sì, esattamente. Quindi dov'è il problema? –

+0

Non sono sicuro di dove sia il problema ma quando torni all'attività imposta prima il valore di Editext dal codice java, quindi imposta il suggerimento con il codice java e Rimuovi il suggerimento dal file xml usalo solo dal codice java. – Herry

risposta

1

finalmente trovato la spiegazione adeguata del problema:

Ebbene si scopre che c'era una l'ottimizzazione delle prestazioni è stata aggiunta a il framework in Android 4.0 che ha consentito alla tua gerarchia di viste solo una sola passata prima dell'avvio dell'animazione Attività. Una volta terminata l'animazione dell'attività , la gerarchia delle viste viene disegnata ogni ~ 16 ms come previsto.

Per saperne di più: https://medium.com/@chrisbanes

TLDR: è la limitazione della piattaforma e questo comportamento si verificherà su versioni precedenti (Marshmallow e inferiore).

L'animazione Torrone funziona come previsto senza il ritardo.

2

mi si avvicinò con una soluzione a basso costo per questo e un altro bug .

sottoclasse il TextInputLayout
See codice per addView()
Se hai testo impostato nella visualizzazione del testo quando viene gonfiata sarà impostato il suggerimento per crollato e prevenire un'animazione. Questo codice esegue una soluzione che imposta temporaneamente il testo fino a quando lo stato non viene impostato durante l'installazione. Come bonus, c'è un codice che assicura che il suggerimento venga tracciato nel caso in cui vi sia un solo passaggio di layout.

public class TextInputLayout extends android.support.design.widget.TextInputLayout { 

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

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

@SuppressLint("DrawAllocation") 
@Override 
protected void onLayout(final boolean changed, final int left, final int top, final int right, final int bottom) { 
    if (ViewCompat.isLaidOut(this)) { 
     super.onLayout(changed, left, top, right, bottom); 
    } else { 
     // Workaround for this terrible logic where onLayout gets called before the view is flagged as laid out. 
     // The normal TextInputLayout is depending on isLaidOut when onLayout is called and failing the check which prevents initial drawing 
     // If there are multiple layout passes this doesn't get broken 
     post(new Runnable() { 
      @SuppressLint("WrongCall") 
      @Override 
      public void run() { 
       TextInputLayout.super.onLayout(changed, left, top, right, bottom); 
      } 
     }); 
    } 
} 

@Override 
public void addView(View child, int index, ViewGroup.LayoutParams params) { 
    if (child instanceof EditText) { 
     EditText editText = (EditText) child; 
     if (StringUtils.isEmpty(editText.getText().toString())) { 
      editText.setText(" "); // Set filler text so the initial state of the floating title is to be collapsed 
      super.addView(child, index, params); 
      editText.setText(""); // Set back to blank to cause the hint to animate in just in case the user sets text 
      // This prevents the hint from being drawn over text that is set programmatically before the state is determined 
      return; 
     } 
    } 
    super.addView(child, index, params); 
} 

}

1

È possibile impostare i suggerimenti di programmazione con un piccolo ritardo. Questa non è una soluzione ideale, ma almeno sembra migliore dei suggerimenti sovrapposti.

new Handler().postDelayed(
    new Runnable() { 
     @Override 
     public void run() { 
     textInputLayout.setHint("My hint"); 
     } 
    }, 100 
); 
0

Penso che questo possa essere fissato per la compilazione 'com.android.support:design:23.0.1'

0

Daniel Ochoa ha notato una soluzione nei commenti, che hanno lavorato per me - impostare lo stato iniziale per il EditText con alcuni contenuti di testo (una stringa vuota dovrebbe farlo). Ciò costringerà lo stato iniziale del suggerimento a salire.

<android.support.design.widget.TextInputLayout 
    android:id="@+id/firstNameTextInputLayout" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_marginTop="8dp"> 

    <EditText 
     android:id="@+id/firstNameEditText" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:hint="@string/first_name" 
     android:inputType="textCapWords" 
     android:textColor="@color/textPrimary" 
     android:textColorHint="@color/textSecondary" 
     android:textSize="16sp" 
     android:theme="@style/CustomEditText" 
     android:text=" "/> 
</android.support.design.widget.TextInputLayout> 
1

La soluzione che ha funzionato per me è stato quello di aggiornare l'attività in questo modo:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    ... 
    textInputLayout.setHintAnimationEnabled(false); 
    textInput.setText("sample"); 
    textInputLayout.setHintAnimationEnabled(true); 
    ... 
}