notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

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 }