tutorial studio example edittext and android android-edittext android-textview android-4.2-jelly-bean

studio - textview and button android example



Error del sistema operativo Android con algunos dispositivos que ejecutan Jelly Bean/4.2.1-TextView.setError(error de CharSequence) Icono que falta (2)

¡Solución temporal! EditTextErrorFixed.java

Si bien este es un error de SDK, he logrado utilizar métodos de reflexión para que el ícono funcione como se esperaba. Comprobé que funciona tanto con 4.2 como 4.2.1 y verifiqué que funciona en mi Galaxy Nexus actualizado.

La fuente se puede encontrar aquí.

La captura de pantalla muestra que el icono en la parte inferior EditTextErrorFixed persiste incluso si el foco cambia. Además, incorpora otra solución donde si el usuario presiona Eliminar en un EditText ya vacío, el error desaparece (¿otro error?).

Para su comodidad, aquí está la fuente EditTextErrorFixed ; la clase se puede usar fácilmente en XML:

package com.olegsv.showerrorfixeddemo; import android.content.Context; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Build; import android.text.TextUtils; import android.util.AttributeSet; import android.view.KeyEvent; import android.widget.EditText; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * EditText which addresses issues with the error icon * (http://stackoverflow.com/q/13756978/832776) and also the error icon * disappearing on pressing delete in an empty EditText */ public class EditTextErrorFixed extends EditText { public EditTextErrorFixed(Context context) { super(context); } public EditTextErrorFixed(Context context, AttributeSet attrs) { super(context, attrs); } public EditTextErrorFixed(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * Don''t send delete key so edit text doesn''t capture it and close error */ @Override public boolean onKeyPreIme(int keyCode, KeyEvent event) { if (TextUtils.isEmpty(getText().toString()) && keyCode == KeyEvent.KEYCODE_DEL) return true; else return super.onKeyPreIme(keyCode, event); } /** * Keep track of which icon we used last */ private Drawable lastErrorIcon = null; /** * Resolve an issue where the error icon is hidden under some cases in JB * due to a bug http://code.google.com/p/android/issues/detail?id=40417 */ @Override public void setError(CharSequence error, Drawable icon) { super.setError(error, icon); lastErrorIcon = icon; // if the error is not null, and we are in JB, force // the error to show if (error != null /* !isFocused() && */) { showErrorIconHax(icon); } } /** * In onFocusChanged() we also have to reshow the error icon as the Editor * hides it. Because Editor is a hidden class we need to cache the last used * icon and use that */ @Override protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { super.onFocusChanged(focused, direction, previouslyFocusedRect); showErrorIconHax(lastErrorIcon); } /** * Use reflection to force the error icon to show. Dirty but resolves the * issue in 4.2 */ private void showErrorIconHax(Drawable icon) { if (icon == null) return; // only for JB 4.2 and 4.2.1 if (android.os.Build.VERSION.SDK_INT != Build.VERSION_CODES.JELLY_BEAN && android.os.Build.VERSION.SDK_INT != Build.VERSION_CODES.JELLY_BEAN_MR1) return; try { Class<?> textview = Class.forName("android.widget.TextView"); Field tEditor = textview.getDeclaredField("mEditor"); tEditor.setAccessible(true); Class<?> editor = Class.forName("android.widget.Editor"); Method privateShowError = editor.getDeclaredMethod("setErrorIcon", Drawable.class); privateShowError.setAccessible(true); privateShowError.invoke(tEditor.get(this), icon); } catch (Exception e) { // e.printStackTrace(); // oh well, we tried } } }

Algunos, pero no todos, los dispositivos que ejecutan Jelly Bean (4.2.1) parecen faltar el icono de error de exclamación que debería aparecer en un TextView (o, más comúnmente, un EditText ) que tiene un error establecido a través de TextView.setError(CharSequence error) .

El Galaxy Nexus definitivamente parece estar perdiendo el ícono.

El efecto es que el estado de error establecido por setError solo es aparente cuando EditText tiene foco. Esto hace que setError(...) mucho menos útil ya que a menudo se usa para alentar a los usuarios a volver a EditText para solucionar un problema. Por ejemplo, tiene una pantalla de inicio de sesión estándar con entradas de formulario de nombre de usuario y contraseña que se validan cuando el usuario hace clic en un botón Enviar. Un mensaje de error de validación establecido en el formulario de nombre de usuario no se mostrará a menos que el usuario haga clic nuevamente en ese formulario, que es lo que el icono de error está diseñado para animarles a hacer.

Para probar: (Puede haber un EditText más fácilmente accesible, pero este está ampliamente disponible)

  1. Configuración abierta
  2. Seleccione ''Agregar cuenta'' (esto está en ''Cuentas y sincronización'' en dispositivos más antiguos)
  3. Seleccione ''Google'' como el tipo de cuenta
  4. Seleccione ''Existente'' (después de hacer clic en ''Siguiente'' y ''Iniciar sesión'' en dispositivos más antiguos)
  5. Dejando en blanco el texto EditText ''Email'', haga clic en ''Password'' EditText

En este punto, se establece un error en EditText ''Correo electrónico'' diciendo que no puede estar en blanco. En dispositivos que no tienen este problema, se muestra el icono de error habitual, que se expande al mensaje de error completo cuando EditText tiene foco. En Galaxy Nexuses ejecutando Jelly Bean, no se muestra ningún icono y el error solo es visible cuando EditText ''Correo electrónico'' EditText enfocar, y todavía carece del ícono en ese punto.

Esto parece un error, pero quería verificar si otras personas pueden reproducirlo, tener ideas sobre cuál podría ser el problema y tener una buena solución.

Usar setError(CharSequence error, Drawable icon) probablemente arreglaría las cosas, pero sería bueno poder usar el gráfico de error de stock en diferentes versiones de Android.


Sé que ya hay una solución aquí. Es solo que trato de evitar la reflexión a toda costa en Android. Si está de acuerdo con la reflexión, intente primero mi solución, ya que podría solucionar el problema sin tener que crear una subclase y reflejar.

Drawable d= getResources().getDrawable(R.drawable.ic_launcher); d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); et.setError("my error",d);