Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EditText hidden by keyboard when android:gravity="center" - Android

OK well, after hours spent looking for a solution, I came here.

I think it might be an issue with Android.

Try to create this simple layout. Open the keyboard, hide it, then open it again and the EditText is hidden.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="300dp"
        android:gravity="center"
        android:inputType="phone"
        android:maxLength="14"
        android:text="some text"
        android:textColor="#666666"
        android:textSize="22sp" />

</RelativeLayout>

Now, remove android:gravity="center" and everything works! Before you ask me, yeah I've already added android:windowSoftInputMode="adjustPan"

Any solution would be greatly appreciated! Thanks

like image 578
Romain Pellerin Avatar asked Nov 01 '22 16:11

Romain Pellerin


1 Answers

I recently dealt with this issue on a Nexus 7 phone. The behaviour didn't otherwise occur on any of our other test phones. The trick seems to be to change the focus BEFORE you close the softkeyboard. The keyboard is closed at 3 points - clicking the Done button, clicking outside of the edittext box, and clicking the back button.

First, create a hidden element to eat your focus

 <MyEditText
           android:id="@+id/editHidden"
            android:layout_width="0dp"
             android:layout_height="0dp"
            android:layout_below="@id/imageLogin"
           />

I stored this but it's a bit ugly...

@Override
    protected void onResume() {
        super.onResume();

        Utils.focusable = findViewById(R.id.editHidden);

Now change the focus to your hidden element when the keyboard is closed.

public static void clearFocus() {
        try {
            if (focusable!=null)
                focusable.requestFocus();
        } catch (Exception e) {}
    }

     public static void hideSoftKeyboard(View view) {
        clearFocus();
        if (view!=null) {
            try {
                InputMethodManager inputMethodManager = (InputMethodManager)  view.getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
                inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
            } catch (Exception e) {}
        }
    }

Then run the hideKeyboard function in the spots the keyboard is closed: EditText back button pressed:

@Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event)
    {
       if(keyCode == KeyEvent.KEYCODE_BACK)
       {
           try {
              Utils.clearFocus();
           } catch (Exception e) {}
       }
       return super.onKeyPreIme(keyCode, event);
    }

Done button pressed, attach this to any EditText boxes the issue is occurring with:

public static OnEditorActionListener getOnEditorActionListener() {
        return new OnEditorActionListener() {        

            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if(actionId==EditorInfo.IME_ACTION_DONE){
                     hideSoftKeyboard(v);
                }

                return false;
            }
        };
    }

Click outside of textbox - attach to all elements on the page in onCreate();

public static void setupUI(View view) {

try {
    //Set up touch listener for non-text box views to hide keyboard.
    if(!(view instanceof EditText)) {

        view.setOnTouchListener(new OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event) {
                hideSoftKeyboard(v);
                return false;
            }

        });
    }

    //If a layout container, iterate over children and seed recursion.
    if (view instanceof ViewGroup) {

        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {

            View innerView = ((ViewGroup) view).getChildAt(i);

            setupUI(innerView);
        }
    }
} catch (Exception e) {}

}

It's pretty messy but did solve the problem, hopefully there's a better way though.

like image 64
stuart_gunn Avatar answered Nov 12 '22 12:11

stuart_gunn