package com.alexvasilkov.android.commons.ui; import android.app.Activity; import android.content.Context; import android.graphics.Rect; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.view.View; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.inputmethod.InputMethodManager; @SuppressWarnings({ "WeakerAccess", "unused" }) // Public API public class KeyboardHelper { private static final int TAG_LISTENER_ID = -10010; private KeyboardHelper() {} /** * Hides keyboard using currently focused view.<br/> * Shortcut for {@link #hideSoftKeyboard(android.content.Context, android.view.View) * hideSoftKeyboard(activity, activity.getCurrentFocus())}. */ public static void hideSoftKeyboard(Activity activity) { hideSoftKeyboard(activity, activity.getCurrentFocus()); } /** * Uses given views to hide soft keyboard and to clear current focus. * * @param context Context * @param focusedView Currently focused view */ public static void hideSoftKeyboard(@NonNull Context context, @Nullable View focusedView) { if (focusedView == null) { return; } final InputMethodManager manager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); manager.hideSoftInputFromWindow(focusedView.getWindowToken(), 0); focusedView.clearFocus(); } /** * Shows soft keyboard and requests focus for given view. */ public static void showSoftKeyboard(Context context, View view) { if (view == null) { return; } final InputMethodManager manager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); view.requestFocus(); manager.showSoftInput(view, 0); } /** * Registers listener for soft keyboard state changes.<br/> * The state is computed based on rootView height changes. * * @param rootView Should be deepest full screen view, i.e. root of the layout passed to * Activity.setContentView(...) or view returned by Fragment.onCreateView(...) * @param listener Keyboard state listener */ public static void addKeyboardListener(@NonNull final View rootView, @NonNull final OnKeyboardShowListener listener) { final OnGlobalLayoutListener layoutListener = new OnGlobalLayoutListener() { private boolean isKeyboardShown; private int initialHeightsDiff = -1; @Override public void onGlobalLayout() { final Rect frame = new Rect(); rootView.getWindowVisibleDisplayFrame(frame); int heightDiff = rootView.getRootView().getHeight() - (frame.bottom - frame.top); if (initialHeightsDiff == -1) { initialHeightsDiff = heightDiff; } heightDiff -= initialHeightsDiff; if (heightDiff > 100) { // If more than 100 pixels, its probably a keyboard... if (!isKeyboardShown) { isKeyboardShown = true; listener.onKeyboardShow(true); } } else if (heightDiff < 50) { if (isKeyboardShown) { isKeyboardShown = false; listener.onKeyboardShow(false); } } } }; rootView.getViewTreeObserver().addOnGlobalLayoutListener(layoutListener); rootView.setTag(TAG_LISTENER_ID, layoutListener); } @SuppressWarnings("deprecation") public static void removeKeyboardListener(@NonNull View rootView) { final OnGlobalLayoutListener layoutListener = (OnGlobalLayoutListener) rootView.getTag(TAG_LISTENER_ID); Views.removeOnGlobalLayoutListener(rootView, layoutListener); } public interface OnKeyboardShowListener { void onKeyboardShow(boolean show); } }