KeyboardHeightProvider.java (5968B)
1 /* 2 * This file is part of Siebe Projects samples. 3 * 4 * Siebe Projects samples is free software: you can redistribute it and/or modify 5 * it under the terms of the Lesser GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * Siebe Projects samples is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * Lesser GNU General Public License for more details. 13 * 14 * You should have received a copy of the Lesser GNU General Public License 15 * along with Siebe Projects samples. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package com.damus.notedeck; 19 20 import android.app.Activity; 21 22 import android.content.res.Configuration; 23 import android.content.res.Resources; 24 import android.util.Log; 25 import android.graphics.Point; 26 import android.graphics.Rect; 27 import android.graphics.drawable.ColorDrawable; 28 import android.util.DisplayMetrics; 29 30 import android.view.Gravity; 31 import android.view.LayoutInflater; 32 import android.view.View; 33 import android.view.ViewTreeObserver.OnGlobalLayoutListener; 34 35 import android.view.WindowManager.LayoutParams; 36 37 import android.widget.PopupWindow; 38 39 40 /** 41 * The keyboard height provider, this class uses a PopupWindow 42 * to calculate the window height when the floating keyboard is opened and closed. 43 */ 44 public class KeyboardHeightProvider extends PopupWindow { 45 46 /** The tag for logging purposes */ 47 private final static String TAG = "sample_KeyboardHeightProvider"; 48 49 /** The keyboard height observer */ 50 private KeyboardHeightObserver observer; 51 52 /** The cached landscape height of the keyboard */ 53 private int keyboardLandscapeHeight; 54 55 /** The cached portrait height of the keyboard */ 56 private int keyboardPortraitHeight; 57 58 /** The view that is used to calculate the keyboard height */ 59 private View popupView; 60 61 /** The parent view */ 62 private View parentView; 63 64 /** The root activity that uses this KeyboardHeightProvider */ 65 private Activity activity; 66 67 /** 68 * Construct a new KeyboardHeightProvider 69 * 70 * @param activity The parent activity 71 */ 72 public KeyboardHeightProvider(Activity activity) { 73 super(activity); 74 this.activity = activity; 75 76 //LayoutInflater inflator = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); 77 //this.popupView = inflator.inflate(android.R.layout.popupwindow, null, false); 78 this.popupView = new View(activity); 79 setContentView(popupView); 80 81 setSoftInputMode(LayoutParams.SOFT_INPUT_ADJUST_RESIZE | LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); 82 setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); 83 84 parentView = activity.findViewById(android.R.id.content); 85 86 setWidth(0); 87 setHeight(LayoutParams.MATCH_PARENT); 88 89 popupView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 90 91 @Override 92 public void onGlobalLayout() { 93 if (popupView != null) { 94 handleOnGlobalLayout(); 95 } 96 } 97 }); 98 } 99 100 /** 101 * Start the KeyboardHeightProvider, this must be called after the onResume of the Activity. 102 * PopupWindows are not allowed to be registered before the onResume has finished 103 * of the Activity. 104 */ 105 public void start() { 106 107 if (!isShowing() && parentView.getWindowToken() != null) { 108 setBackgroundDrawable(new ColorDrawable(0)); 109 showAtLocation(parentView, Gravity.NO_GRAVITY, 0, 0); 110 } 111 } 112 113 /** 114 * Close the keyboard height provider, 115 * this provider will not be used anymore. 116 */ 117 public void close() { 118 this.observer = null; 119 dismiss(); 120 } 121 122 /** 123 * Set the keyboard height observer to this provider. The 124 * observer will be notified when the keyboard height has changed. 125 * For example when the keyboard is opened or closed. 126 * 127 * @param observer The observer to be added to this provider. 128 */ 129 public void setKeyboardHeightObserver(KeyboardHeightObserver observer) { 130 this.observer = observer; 131 } 132 133 /** 134 * Popup window itself is as big as the window of the Activity. 135 * The keyboard can then be calculated by extracting the popup view bottom 136 * from the activity window height. 137 */ 138 private void handleOnGlobalLayout() { 139 140 Point screenSize = new Point(); 141 activity.getWindowManager().getDefaultDisplay().getSize(screenSize); 142 143 Rect rect = new Rect(); 144 popupView.getWindowVisibleDisplayFrame(rect); 145 146 // REMIND, you may like to change this using the fullscreen size of the phone 147 // and also using the status bar and navigation bar heights of the phone to calculate 148 // the keyboard height. But this worked fine on a Nexus. 149 int orientation = getScreenOrientation(); 150 int keyboardHeight = screenSize.y - rect.bottom; 151 152 if (keyboardHeight == 0) { 153 notifyKeyboardHeightChanged(0, orientation); 154 } 155 else if (orientation == Configuration.ORIENTATION_PORTRAIT) { 156 this.keyboardPortraitHeight = keyboardHeight; 157 notifyKeyboardHeightChanged(keyboardPortraitHeight, orientation); 158 } 159 else { 160 this.keyboardLandscapeHeight = keyboardHeight; 161 notifyKeyboardHeightChanged(keyboardLandscapeHeight, orientation); 162 } 163 } 164 165 private int getScreenOrientation() { 166 return activity.getResources().getConfiguration().orientation; 167 } 168 169 private void notifyKeyboardHeightChanged(int height, int orientation) { 170 if (observer != null) { 171 observer.onKeyboardHeightChanged(height, orientation); 172 } 173 } 174 }