1. 程式人生 > >ionic-鍵盤覆蓋輸入框和返回鍵問題解決方案

ionic-鍵盤覆蓋輸入框和返回鍵問題解決方案

第一個問題:
(1)我們知道ionic的底部的<ion-footer-bar>這個標籤,是固定在底部的,而且也是脫離文件流的,那麼我們可以將我們的評論框定義在<ion-footer-bar>這個標籤中,那麼我們已經省去了很多的工作,因為<ion-footer-bar>已經幫我們至少固定在底部了。

<ion-footer-bar keyboardshow class="bar item-input-inset">
<label class="item-input-wrapper" >
<i class="icon ion-edit placeholder-icon"></i>
<input type="tel" placeholder="說點什麼">
</label>
<button class="button button-positive">傳送</button>   
</ion-footer-bar>

具體的樣式:


(2)我們可以在瀏覽器上通過查詢器可以檢視到<ion-footer-bar>或者它的類這個標籤的css樣色,其中可以知道它的位置是絕對位置,而且bottom是等於0的,所以如果我們可以在點選input輸入時,能夠實時獲取鍵盤的高度height的話,那麼就可以將<ion-footer-bar>的bottom位置設定為鍵盤高度height,那麼將不會再擋住輸入框了。所以我們需要新增ionic-plugins-keyboard這個外掛,這個外掛的github:https://github.com/driftyco/ionic-plugins-keyboard.
這個外掛裡面我們需要注意三個方法:
(a)、window.addEventListener('native.keyboardshow', keyboardShowHandler);
function keyboardShowHandler(e){
    alert('Keyboard height is: ' + e.keyboardHeight);
}
這個方法是監聽鍵盤彈出,e.keyboardHeight這個就是鍵盤的高度
(b)、window.addEventListener('native.keyboardhide', keyboardHideHandler);
function keyboardHideHandler(e){
    alert('Goodnight, sweet prince');
}
這個方法是將它鍵盤的隱藏

(c)、cordova.plugins.Keyboard.close();
這個方法是關閉鍵盤,相當於銷燬整個物件

一個屬性:cordova.plugins.Keyboard.isVisible。 boolean值,判斷鍵盤是否是活動彈出來的

我們大致瞭解這個外掛的功能後,接下來自定義一個指令,這裡叫keyboardshow
.directive('keyboardshow', function($rootScope, $ionicPlatform, $timeout, $ionicHistory, $cordovaKeyboard) {
    return {
        restrict: 'A',
        link: function(scope, element, attributes) {
            window.addEventListener('native.keyboardshow',function (e){              
                   return ;
            });

            window.addEventListener('native.keyboardhide',function (e){
                angular.element(element).css({
                  'bottom':0
                });
            });
        }
    };
});


那麼在<ion-footer-bar keyboardshow class="bar item-input-inset">,可以看到這個指令,也就是在我們進入閱讀這一篇文章的時候,angularjs就會解釋這個指令,監聽這個鍵盤是否彈出或者隱藏,一旦我們點選input輸入框,那麼系統就會呼叫鍵盤,這個時候就會監聽到native.keyboardshow事件,這個時候執行一個css樣色修改:
angular.element(element).css({
    'bottom':e.keyboardHeight + 'px'
});
因為是絕對的位置,所以,評論框就會定位在鍵盤的上方,不會出現覆蓋。

如果我們點選鍵盤的隱藏鍵,那麼將會將聽到native.keyboardhide這個事件,這個時候,我們再把bottom設定為0,也就是回到原來的位置。

至此我們已經解決了鍵盤擋住的問題了。
截圖:


第二個問題:
首先我們需要在run中:
.run(function($ionicPlatform, $ionicHistory, $cordovaKeyboard) {
   e.preventDefault();
  $ionicPlatform.registerBackButtonAction(function (e) {
      if($ionicHistory.backView()) {
          if($cordovaKeyboard.isVisible()) {
            $cordovaKeyboard.close();
          }else {
            $ionicHistory.goBack();
          }
      }
  }, 101);
$ionicPlatform.registerBackButtonAction是註冊一個返回按鈕的事件處理,優先順序為101。
ionic在底層原始碼中定義了物理返回按鍵的事件處理優先順序的:
var PLATFORM_BACK_BUTTON_PRIORITY_VIEW = 100;  
var PLATFORM_BACK_BUTTON_PRIORITY_SIDE_MENU = 150;  
var PLATFORM_BACK_BUTTON_PRIORITY_MODAL = 200;  
var PLATFORM_BACK_BUTTON_PRIORITY_ACTION_SHEET = 300;  
var PLATFORM_BACK_BUTTON_PRIORITY_POPUP = 400;  
var PLATFORM_BACK_BUTTON_PRIORITY_LOADING = 500; 
數字越大,優先順序就越高,越先執行。


100優先順序是返回上一頁,那麼我們定義101就是在鍵盤彈出的情況下,點選返回鍵是執行101,將鍵盤收起來,並不是返回上一頁,當再次點選時,再返回上一頁。
下面的程式碼分析一下:
if($ionicHistory.backView()) {
  if($cordovaKeyboard.isVisible()) {
    $cordovaKeyboard.close();
  }else {
    $ionicHistory.goBack();
  }
}

當點選返回鍵時,首先判斷是否有上一頁的檢視存在,如果有存在,那麼在判斷當前的鍵盤是否是彈出活動的,如果是,則將鍵盤關閉,如果沒有鍵盤彈出,那麼就是直接返回上一頁。

在這裡特別要注意的是,這個外掛監聽的是android原生的鍵盤,也就是google輸入法,如果使用google輸入法的話,這個是正常的了,點選返回鍵,鍵盤收起來,也沒有返回上一頁!
但是一般的第三輸入法,比如搜狗輸入法,百度輸入法,訊飛輸入法等,這個$cordovaKeyboard.isVisible()獲取的值會是false。也就是說在點選返回鍵時,鍵盤收起來,同時頁面還是返回上一頁了,然而這並不是我們所希望的。

那麼有什麼辦法解決嗎,可以讓不管是什麼輸入法都能滿足條件呢?
辦法當然是有的,我們知道當點選返回鍵時,鍵盤關閉,此時執行:
window.addEventListener('native.keyboardhide',function (e){
angular.element(element).css({
 'bottom':0
});
});

那麼在這裡$cordovaKeyboard.isVisible()獲取到的值已經變成了false,也就是說,先執行這段程式碼,再執行註冊的那一段返回按鈕的程式碼,所以想個辦法讓isVisible延時再賦值:
window.addEventListener('native.keyboardhide',function (e){
    angular.element(element).css({
      'bottom':0
    });

    cordova.plugins.Keyboard.isVisible = true;
    $timeout(function() {
      cordova.plugins.Keyboard.isVisible = false;
    },100);
  
});