Android EditText, soft keyboard show/hide event?

59,949

Solution 1

Hi I'd used following workaround:

As far as my content view is a subclass of LinearLayout (could be any other view or view group), I'd overridden onMeasure method lilke following:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int proposedheight = MeasureSpec.getSize(heightMeasureSpec);
    final int actualHeight = getHeight();

    if (actualHeight > proposedheight){
        // Keyboard is shown
    } else {
        // Keyboard is hidden
    }

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

This workaround helped me to hide some controls when keyboard is showing and bring back otherwise.

Hope this would be useful.

Solution 2

There actually isn't such an event to catch. The IME is simply showing and hiding its window; the feedback you get from this is the window manager causing your own window's content to resize if you have put it in resize mode.

Solution 3

I solved this issue by using onGlobalLayoutListener :

 final View activityRootView = findViewById(R.id.top_root);
        activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();

                if (heightDiff > 100) {
                    // keyboard is up
                } else {
                    // keyboard is down
                }
            }
        });

Here activityRootView is your Activity's root view.

Solution 4

In my case I wanted to hide a bottom bar when softkeyboard was shown. I considered best to just hide the bar when layout had less than a percent size of normal layout size. So I used this solution that works fine considering that soft keyboard usually takes 20% or more screen height. Just change the percent constant by any value you may think is ok. It needs attribute android:windowSoftInputMode="adjustResize" in manifest and layout must be the root to work.

Extend from any layout you may want instead of RelativeLayout.

public class SoftKeyboardLsnedRelativeLayout extends RelativeLayout {
    private boolean isKeyboardShown = false;
    private List<SoftKeyboardLsner> lsners=new ArrayList<SoftKeyboardLsner>();
    private float layoutMaxH = 0f; // max measured height is considered layout normal size
    private static final float DETECT_ON_SIZE_PERCENT = 0.8f;

    public SoftKeyboardLsnedRelativeLayout(Context context) {
        super(context);
    }

    public SoftKeyboardLsnedRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @SuppressLint("NewApi")
    public SoftKeyboardLsnedRelativeLayout(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int newH = MeasureSpec.getSize(heightMeasureSpec);
        if (newH > layoutMaxH) {
            layoutMaxH = newH;
        }
        if (layoutMaxH != 0f) {
            final float sizePercent = newH / layoutMaxH;
            if (!isKeyboardShown && sizePercent <= DETECT_ON_SIZE_PERCENT) {
                isKeyboardShown = true;
                for (final SoftKeyboardLsner lsner : lsners) {
                    lsner.onSoftKeyboardShow();
                }
            } else if (isKeyboardShown && sizePercent > DETECT_ON_SIZE_PERCENT) {
                isKeyboardShown = false;
                for (final SoftKeyboardLsner lsner : lsners) {
                    lsner.onSoftKeyboardHide();
                }
            }
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void addSoftKeyboardLsner(SoftKeyboardLsner lsner) {
        lsners.add(lsner);
    }

    public void removeSoftKeyboardLsner(SoftKeyboardLsner lsner) {
        lsners.remove(lsner);
    }

    // Callback
    public interface SoftKeyboardLsner {
        public void onSoftKeyboardShow();
        public void onSoftKeyboardHide();
    }
}

Example:

layout/my_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<yourclasspackage.SoftKeyboardLsnedRelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/myLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    ...
</yourclasspackage.SoftKeyboardLsnedRelativeLayout>

MyActivity.java

public class MyActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_layout);
        SoftKeyboardLsnedRelativeLayout layout = (SoftKeyboardLsnedRelativeLayout) findViewById(R.id.myLayout);
        layout.addSoftKeyboardLsner(new SoftKeyboardLsner() {
            @Override
            public void onSoftKeyboardShow() {
                Log.d("SoftKeyboard", "Soft keyboard shown");
            }

            @Override
            public void onSoftKeyboardHide() {
                Log.d("SoftKeyboard", "Soft keyboard hidden");
            }
        });
    }
}

Solution 5

try these methods: showSoftInput(View, int, ResultReceiver) and hideSoftInputFromWindow(IBinder, int, ResultReceiver). You can override onReceiveResult(int resultCode, Bundle resultData) method of ResultReceiver class to handle show/hide event.

Share:
59,949

Related videos on Youtube

shkim
Author by

shkim

Contract Programmer

Updated on October 12, 2020

Comments

  • shkim
    shkim over 3 years

    Is it possible to catch the event that Soft Keyboard was shown or hidden for EditText?

  • DiveInto
    DiveInto about 13 years
    how to get the window content resize event?
  • David Homes
    David Homes over 11 years
    where does one add this override? I've a SherlockActivty inflated from a LinearLayout but keep getting that the method is not defined for the class
  • Dmitry Zaytsev
    Dmitry Zaytsev over 11 years
    @dhomes it's not method of Activity. It's method of View. Create your custom View and override this method.
  • verybadalloc
    verybadalloc almost 11 years
    This works for the Hard keyboard, while the OP specifically asked for the softKeyboard events.
  • adamdport
    adamdport over 9 years
    On some devices (eg. Samsung), the predictive text feature causes issues with this solution. I worked around this by setting the inputType on my edittexts to "textVisiblePassword" to disable it.
  • TWiStErRob
    TWiStErRob about 9 years
    This way you'll only receive a callback when your requested action has been done. But not when any future events happen. It would be nice if we receive the user's hide events (e.g. back button) when handed a ResultReceiver to showSoftInput, but that's not the case.