Skip to content

Instantly share code, notes, and snippets.

@tinmegali
Last active February 19, 2016 14:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tinmegali/7037580219292ee93753 to your computer and use it in GitHub Desktop.
Save tinmegali/7037580219292ee93753 to your computer and use it in GitHub Desktop.
This Generic Activity provides events to detect the presence of android's SoftKeyboard
import android.app.Activity;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
/**
* This Activity provides the possibility to register a Listener
* to monitor the SoftKeyboard presence.
* Its not an exact science, but gets the job done.
* Detecting changes that occurred on the registered layout root
* the observer can suppose if the keyboard is present or not.
*
* - To use start the monitoring with {@link #startDetectRootViewChanges(View)}
* and override {@link #onKeyBoardOn()} {@link #onKeyBoardOff()}
*
*/
public class ActivitySoftKeyboard extends Activity {
protected final String TAG = getClass().getSimpleName();
@Override
protected void onDestroy() {
super.onDestroy();
// Remove LayoutChange listener
stopDetectRootViewChanges();
}
/**
* Detecting Layout Root changes
* - {@link #startDetectRootViewChanges(View)} must be called on {@link #onCreate(Bundle)}
* - Detect if SoftKeyboard is On/Off
* {@link #onKeyBoardOn()} {@link #onKeyBoardOff()}
* - Register event for layout changes
* {@link #onRootLayoutChanged(int)}
*/
protected View mActivityRootView;
protected ViewTreeObserver.OnGlobalLayoutListener mLayoutListener;
/**
* Create a new Global Layout Listener
*/
private ViewTreeObserver.OnGlobalLayoutListener createLayoutListener() {
Log.d(TAG, "createLayoutListener");
final int KEYBOARD_GREATER_THAN = 125;
return new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect rect = new Rect();
mActivityRootView.getWindowVisibleDisplayFrame(rect);
int heightDiff = mActivityRootView.getHeight() - (rect.bottom - rect.top);
if (heightDiff>0) onRootLayoutChanged(heightDiff);
if (heightDiff > KEYBOARD_GREATER_THAN) { // if more than 100 pixels, its probably a keyboard...
Log.d(TAG, "onGlobalLayout(). Probabaly a keyBoard. > heightDiff[" + heightDiff + "]");
onKeyBoardOn();
mIsKeyboardOn = true;
} else {
if (mIsKeyboardOn) {
onKeyBoardOff();
mIsKeyboardOn = false;
}
}
}
};
}
/**
* Start to detect changed on Root layout height
* - Register a Root view
* - Create and starts a Global Layout Listener
* - Register root view layout events
* {@link #onKeyBoardOn()}
* {@link #onKeyBoardOff()}
* {@link #onRootLayoutChanged(int)}
* @param activityRootView Root layout to be monitored
*/
protected void startDetectRootViewChanges(final View activityRootView) {
Log.d(TAG, "startDetectRootViewChanges()");
mActivityRootView = activityRootView;
mIsKeyboardOn = false;
mLayoutListener = createLayoutListener();
mActivityRootView.getViewTreeObserver().addOnGlobalLayoutListener(mLayoutListener);
}
/**
* Remove Global Layout change listener
*/
protected void stopDetectRootViewChanges() {
Log.d(TAG, "stopDetectRootViewChanges()");
if ( mActivityRootView != null )
mActivityRootView.getViewTreeObserver().removeOnGlobalLayoutListener(mLayoutListener);
}
private Boolean mIsKeyboardOn;
/**
* Controls if SoftKeyBoard is on/off
* - May return null if {@link #startDetectRootViewChanges(View)} wasn't called
*/
protected Boolean isKeyboardOn() {
Log.d(TAG, "isKeyboardOn()");
return mIsKeyboardOn;
}
/**
* Called on SoftKeyBoard is ON
* - Depends on {@link #startDetectRootViewChanges(View)}
* - It must be called more than one time
*/
protected void onKeyBoardOn() {
Log.d(TAG, "onKeyBoardOn()");
}
/**
* Called on SoftKeyBoard is OFF
* - Depends on {@link #startDetectRootViewChanges(View)}
* - It must be called more than one time
*/
protected synchronized void onKeyBoardOff() {
Log.d(TAG, "onKeyBoardOff()");
}
/**
* Called when Root Layout view changes
* - Depends on {@link #startDetectRootViewChanges(View)}
* @param heightDiff Height Difference between current
* Root View an available Windo size
*/
protected void onRootLayoutChanged(int heightDiff) {
Log.d(TAG, "onRootLayoutChanged(heightDiff[" + heightDiff + "])");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment