Android OS bug with some devices running Jelly Bean/4.2.1 - TextView.setError(CharSequence error) Missing icon

后端 未结 2 754
轻奢々
轻奢々 2021-01-31 15:51

Some, but not all, devices running Jelly Bean (4.2.1) appear to be missing the exclamation point error icon that should appear on a TextView (or, more commonly, an

相关标签:
2条回答
  • 2021-01-31 16:44

    I know there is a solution already here. Its just i try to avoid reflection at all costs on Android. If your ok with reflection go for it but try out my solution below first as it might fix the issue without having to subclass and reflect.

    Drawable d= getResources().getDrawable(R.drawable.ic_launcher);
                d.setBounds(0, 0, 
                        d.getIntrinsicWidth(), d.getIntrinsicHeight());
    
                et.setError("my error",d);
    
    0 讨论(0)
  • 2021-01-31 16:45

    Temporary Solution! EditTextErrorFixed.java

    While this is indeed an SDK bug, I've managed to use reflection methods to get the icon to work as intended. I checked that it works with both 4.2 and 4.2.1 and verified that it works on my updated Galaxy Nexus.

    The source can be found here.

    The screenshot shows that the icon on the bottom EditTextErrorFixed persists even if the focus changes. In addition it incorporates another fix where if the user presses Delete on an already empty EditText the error disappears (another bug?).

    Demo image

    For convenience, here is the EditTextErrorFixed source; the class can easily be used in 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
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题