Android: Error popup on EditText doesn't move down when keyboard goes away

前端 未结 5 1596
太阳男子
太阳男子 2020-12-16 00:04

I have an activity that displays a few EditTexts on screen for user input. To be sure the soft keyboard doesn\'t cover my fields when it displays I have set the property

相关标签:
5条回答
  • 2020-12-16 00:12

    I found the the SOLUTION!

    Here is the code:

    import android.content.Context;
    import android.os.Handler;
    import android.support.v7.widget.AppCompatEditText;
    import android.util.AttributeSet;
    import android.view.KeyEvent;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.inputmethod.InputMethodManager;
    
    /**
     * Created by Jaume Colom Ferrer on 14/12/2015
     */
    public class EditTextPopUpFixed extends AppCompatEditText {
    
        private static final int TIME_SLEEP = 500;
    
        private Context ctx;
        private EditTextListener mListener;
        private int backTimes = 0;
    
        public EditTextPopUpFixed(Context context) {
            super(context);
            ctx = context;
        }
    
        public EditTextPopUpFixed(Context context, AttributeSet attrs) {
            super(context, attrs);
            ctx = context;
        }
    
        public EditTextPopUpFixed(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            ctx = context;
        }
    
        public void setEditTextListener(EditTextListener lis) {
            mListener = lis;
    
            this.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
    
                    backTimes = 0;
                    return false;
                }
            });
        }
    
        @Override
        public boolean onKeyPreIme(int keyCode, KeyEvent event) {
    
            if (keyCode == KeyEvent.KEYCODE_BACK)
                backTimes++;
    
            if (backTimes == 3) {
                backTimes = 0;
                mListener.close();
                return true;
            }
    
            if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ENTER) {
                InputMethodManager mgr = (InputMethodManager) ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
                if (mgr.isActive()) {
                    mgr.hideSoftInputFromWindow(this.getWindowToken(), 0);
                    boolean mustRevalidate = getError() != null;
                    setError(null);
                    if (mListener != null && mustRevalidate) {
                        Handler han = new Handler();
                        han.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                mListener.revalidateEditText();
                            }
                        }, TIME_SLEEP);
                    }
                } else {
                    backTimes = 0;
                    super.onKeyPreIme(keyCode, event);
                }
                return true;
            }
            return false;
        }
    
        public interface EditTextListener {
            void revalidateEditText(); //Revalidates the EditText to refresh the Popup (Must revalidate the EditText in its implementation)
    
            void close(); // Method to close the activity or fragment (Must finish activity or go back in its implementation)
        }
    }
    

    You can use this Custom EditText to solve this bug. It refreshes the Error, after keyboard open/close, and your popup will always be displayed correctly.

    You must implement close(finish or onBackPressed) and revalidate edittext methods in your class.

    0 讨论(0)
  • 2020-12-16 00:27

    Have you tried validating your view, i.e. calling invalidate() method of your view.

    try editText.invalidate();

    Thanks.

    0 讨论(0)
  • 2020-12-16 00:34

    If this is as you described, I think this may be a genuine bug, so may be worth writing it up on the Android Source site.

    So evidently I can only think of hack work arounds!

    Override when the keyboard disappears:

    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
     if (keyCode == KeyEvent.KEYCODE_BACK && 
         event.getAction() == KeyEvent.ACTION_UP) {
             revalidateEditText();
             return false;
     }
     return super.dispatchKeyEvent(event);
    }
    
    public void revalidateEditText(){
           // Dismiss your origial error dialog           
           setError(null);
           // figure out which EditText it is, you already have this code
           // call your validator like in the Q
           validate(editText); // or whatever your equivalent is
    }
    

    This will revalidate your EditText, dismiss your error dialog and re-show it.

    How's that sound?

    Inspired by: Get back key event on EditText

    0 讨论(0)
  • 2020-12-16 00:34

    For me, it helped to wrap the layout in a ScrollView. After this, all the scrolling of the setError-box worked fine.

    0 讨论(0)
  • 2020-12-16 00:38

    You can also create Your custom EditText and override method onKeyPreIme(int keyCode, KeyEvent event)

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
            clearFocus();
            return false;
        }
    }
    
    0 讨论(0)
提交回复
热议问题