Soft keyboard open and close listener in an activity in Android
Piece of cake with the awesomeKeyboardVisibilityEvent library
KeyboardVisibilityEvent.setEventListener( getActivity(), new KeyboardVisibilityEventListener() { @Override public void onVisibilityChanged(boolean isOpen) { // Ah... at last. do your thing :) } });
Credits for Yasuhiro SHIMIZU
This only works when android:windowSoftInputMode
of your activity is set to adjustResize
in the manifest. You can use a layout listener to see if the root layout of your activity is resized by the keyboard.
I use something like the following base class for my activities:
public class BaseActivity extends Activity { private ViewTreeObserver.OnGlobalLayoutListener keyboardLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int heightDiff = rootLayout.getRootView().getHeight() - rootLayout.getHeight(); int contentViewTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop(); LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(BaseActivity.this); if(heightDiff <= contentViewTop){ onHideKeyboard(); Intent intent = new Intent("KeyboardWillHide"); broadcastManager.sendBroadcast(intent); } else { int keyboardHeight = heightDiff - contentViewTop; onShowKeyboard(keyboardHeight); Intent intent = new Intent("KeyboardWillShow"); intent.putExtra("KeyboardHeight", keyboardHeight); broadcastManager.sendBroadcast(intent); } } }; private boolean keyboardListenersAttached = false; private ViewGroup rootLayout; protected void onShowKeyboard(int keyboardHeight) {} protected void onHideKeyboard() {} protected void attachKeyboardListeners() { if (keyboardListenersAttached) { return; } rootLayout = (ViewGroup) findViewById(R.id.rootLayout); rootLayout.getViewTreeObserver().addOnGlobalLayoutListener(keyboardLayoutListener); keyboardListenersAttached = true; } @Override protected void onDestroy() { super.onDestroy(); if (keyboardListenersAttached) { rootLayout.getViewTreeObserver().removeGlobalOnLayoutListener(keyboardLayoutListener); } }}
The following example activity uses this to hide a view when the keyboard is shown and show it again when the keyboard is hidden.
The xml layout:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rootLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ScrollView android:id="@+id/scrollView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > <!-- omitted for brevity --> </ScrollView> <LinearLayout android:id="@+id/bottomContainer" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <!-- omitted for brevity --> </LinearLayout></LinearLayout>
And the activity:
public class TestActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.test_activity); attachKeyboardListeners(); } @Override protected void onShowKeyboard(int keyboardHeight) { // do things when keyboard is shown bottomContainer.setVisibility(View.GONE); } @Override protected void onHideKeyboard() { // do things when keyboard is hidden bottomContainer.setVisibility(View.VISIBLE); } }
As Vikram pointed out in the comments, detecting whether the softkeyboard is shown or has disappeared is only possible with some ugly hacks.
Maybe it is enough to set a focus listener on the edittext:
yourEditText.setOnFocusChangeListener(new OnFocusChangeListener() {@Overridepublic void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { //got focus } else { //lost focus } }});