J'ai récemment utilisé TextInputLayout
et sa méthode setError()
. Le problème que je me pose, c’est que, lorsque j’ai effacé l’erreur en appelant setError(null)
, il reste tellement d’espace vide en bas.
Ordinaire:
Avec erreur:
Après avoir effacé l'erreur:
Après avoir regardé la source, j’ai trouvé qu’ils rendaient la vue INVISIBLE
au lieu de GONE
.setListener(new ViewPropertyAnimatorListenerAdapter() { @Override public void onAnimationEnd(View view) { view.setVisibility(INVISIBLE); // here it is updateLabelVisibility(true); } }).start();
Je me demande pourquoi c'est comme ça? Comment résoudre cela pour éviter l'espace vide?
Consultez la documentation pour
public void setErrorEnabled (boolean enabled)
Ça dit
Indique si la fonctionnalité d'erreur est activée ou non dans cette présentation . Activer cette fonctionnalité avant de définir un message d'erreur via setError (CharSequence) signifiera que cette disposition ne changera pas taille quand une erreur est affichée.
Sur cette base, essayez de définir setErrorEnabled(true)
avant setError()
et de définir setErrorEnabled(false)
après setError(null)
.
La méthode setErrorEnabled(false)
efface l'espace supplémentaire, appelez-la après setError(null)
.
Voir ceci page. Google publiera le correctif dans la future version de la bibliothèque de support. Ça dit,
Si vous voulez résoudre ce problème maintenant, vous pouvez étendre
TextInputLayout
et écrasez la méthodesetErrorEnabled()
, mais je ne peux pas garantir le rétrocompatibilité. Parce que son danger de changer d'état enTextInputLayout
.public class TextInputLayout extends Android.support.design.widget.TextInputLayout{ public TextInputLayout(Context context) { super(context); } public TextInputLayout(Context context, AttributeSet attrs) { super(context, attrs); } public TextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void setErrorEnabled(boolean enabled) { super.setErrorEnabled(enabled); if (enabled) { return; } if (getChildCount() > 1) { View view = getChildAt(1); if (view != null) { view.setVisibility(View.GONE); } } } }
Je crée une vue personnalisée pour éviter le code répété et substitue la méthode setError
.
public class UserInputView extends TextInputLayout {
public UserInputView(Context context) {
this(context, null);
}
public UserInputView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public UserInputView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setError(@Nullable CharSequence error) {
boolean isErrorEnabled = error != null;
setErrorEnabled(isErrorEnabled);
super.setError(error);
}
}
Ne pas utiliser setErrorEnabled(boolean)
, il ne montre tout simplement pas l'erreur de la deuxième fois.
public class MyTextInputLayout extends Android.support.design.widget.TextInputLayout {
public MyTextInputLayout(Context context) {
super(context);
}
public MyTextInputLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setError(@Nullable CharSequence error) {
super.setError(error);
View layout = getChildAt(1);
if (layout != null) {
if (error != null && !"".equals(error.toString().trim())) {
layout.setVisibility(VISIBLE);
} else {
layout.setVisibility(GONE);
}
}
}
}
Alors juste setError(errorMessage);
ou setError(null);
Le code source de TextInputLayout indique ce qui suit: Si vous devez effacer l’erreur, utilisez simplement
til.setErrorEnabled(false);
Cela cachera le texte d'erreur et réduira l'espace du bas à sa taille standard.
Si vous devez redéfinir l'erreur, utilisez simplement
til.setError("Your text");
qui appelle automatiquement til.setErrorEnabled(true)
car il suppose que vous avez besoin de la fonctionnalité d'erreur.
En utilisant mTextInputLayout.setErrorEnabled(false);
j'ai résolu ce problème
Le code suivant fonctionne bien
textInputLatout.getEditText().addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length() < 1) {
textInputLayout.setErrorEnabled(true);
textInputLayout.setError("Please enter a value");
}
if (s.length() > 0) {
textInputLayout.setError(null);
textInputLayout.setErrorEnabled(false);
}
}
@Override
public void afterTextChanged(Editable s) {
}
});