【问题标题】:Ionic Cordova Windows 10 - How to detect soft keyboardIonic Cordova Windows 10 - 如何检测软键盘
【发布时间】:2020-04-20 20:38:54
【问题描述】:

我有一个 Ionic / Cordova 应用程序,我(也)为 Windows 10 (UWP) 构建。

在平板电脑(例如 Microsoft Surface)上,我希望能够在调用软键盘时缩小应用程序。

我还没有找到这样做的直接方法,因此作为一种解决方法,我在输入焦点/模糊事件上执行此操作,但是,我至少希望能够确定是否使用软键盘正在使用,所以我在桌面上运行时不会这样做。

这是我的尝试(不起作用)

    public static isUsingWindowSoftKeyboard(): boolean {
        try {
          Utils.logger.info('isUsingWindowSoftKeyboard begin');
          if (!Utils.isWindows())
            return false;

          let w: any = window;
          let touchCapabilities = new w.Windows.Devices.Input.TouchCapabilities();

          let ss = stringify(touchCapabilities);
          Utils.logger.info(ss);
          let keyboardCapabilities = new w.Windows.Devices.Input.KeyboardCapabilities();

          ss = stringify(keyboardCapabilities);
          Utils.logger.info(ss);

          Utils.logger.info('isUsingWindowSoftKeyboard end')

          return true;
        } catch (error) {
          Utils.logger.error(`Utils.isUsingWindowSoftKeyboard: ${error}`);
          return false;
        }
      }

在上面当我注销 ss 变量(我似乎能够在 Windows 上获得任何调试信息的唯一方法)时,它只是空的,所以我假设调用 TouchCapabilities() 和 @987654324 @ 只是不工作。

是否有人对我如何能够做到我上面描述的事情有任何其他建议?

[EDIT1]

我做得还不够。尽管stringify 没有显示任何内容,但至少其中一个属性确实存在(也许它们实际上是getters)。

无论如何,以下 DID 在桌面上运行时为键盘返回 1..

 let keyboardCapabilities = new w.Windows.Devices.Input.KeyboardCapabilities();
 Utils.logger.info(`Keyboard present: ${keyboardCapabilities.keyboardPresent}`);

我还尝试了触摸功能属性...

let touchCapabilities = new w.Windows.Devices.Input.TouchCapabilities();      
Utils.logger.info(`touch present: ${touchCapabilities.TouchPresent}`);
Utils.logger.info(`Contacts: ${touchCapabilities.Contacts}`);

这两个都报告了undefined,但它确实表明属性touchCapabilitiesIS已定义,否则我在尝试访问这两个属性时会遇到空异常。

我现在只需要在带有触摸屏的平板电脑上进行测试(我可以在回到办公室时使用 Surface 平板电脑进行测试)。

我需要重新调查的另一个途径是使用getForCurrentView(),如下所示..

  let w: any = window;
  let vm = w.Windows.UI.ViewManagement;
  this.logger.info(`vm is ${(vm ? "defined" : "undefined")}`);

  let ip = vm.InputPane;
  this.logger.info(`ip is ${(ip ? "defined" : "undefined")}`);

  let inputPane = vm.InputPane.getForCurrentView();
  this.logger.info(`inputPane is ${(inputPane ? "defined" : "undefined")}`);

  if (inputPane) {
    inputPane.addEventListener('show', async ev => {
      this.logger.info(`inputPane show fired !!!`);
    })
  }

我没有让上述方法起作用,但我确实看到在其他搜索中提到了getForCurrentView(),即使在winjs 的上下文中也是如此。也许我打错地方了,所以再试一次。如果这可行,那就更好了,因为使用 show 和 'hide' 事件我可以调整应用程序的大小,即使用户手动关闭软键盘而不是依赖输入 focusblur

【问题讨论】:

    标签: cordova ionic-framework uwp


    【解决方案1】:

    这对我有用。我不妨添加整个班级。它的“要点”在于添加到w.Windows.UI.ViewManagement.InputPane.getForCurrentView()的两个监听器

    我添加了以下服务,我从主组件ngAfterViewInit()调用它

        import { Injectable } from '@angular/core';
        import { Utils } from '@shared/utils';
        import { Logger } from './logger.service';
    
        /**
         * Manages the Windows soft keyboard showing / hiding and resizing the app when it is shown/hidden
         */
        @Injectable()
        export class WindowsKeyboardService {
          /**
           * Construction
           * @param logger - logger
           */
          constructor(private logger: Logger) { }
    
          /**
           * Call from main component once the view is visible, so we can get access to Windows Input pane
           * and hook up the soft keyboard handlers
           */
          public async hookupKeyboardHandlers() : Promise<void> {
            try {
              this.logger.info('hookupKeyboardHandlers');
    
              // Only need this for Windows. For ioS/Android the keyboard plugin does all this for us.
              if (!await Utils.isWindows()) {
                this.logger.info('WindowsKeyboardService.hookupKeyboardHandlers - not windows. Skipping');
                return;
              }
    
              let w = <any>window;
              const inputPane = w.Windows.UI.ViewManagement.InputPane.getForCurrentView();
              if (!inputPane) {
                this.logger.error('WindowsKeyboardService.hookupKeyboardHandlers: could not get inputPane');
                return;
              }
    
              inputPane.addEventListener('showing', _ => this.onWindowsKeyboardUp);
              inputPane.addEventListener('hiding', _ => this.onWindowsKeyboardClose);            
            } catch (error) {
              this.logger.error(`WindowsKeyboardService.hookupKeyboardHandlers: ${error}`)
            }
          }
    
         /**
         * Raised when a Windows soft keyboard is opened
         */
          private onWindowsKeyboardUp() : void {
            try {
              this.logger.info("onWindowKeyboardUp");
    
              // Just half viewportHeight for now (until can find out how to get keyboard height - if even possible)
              let viewportHeight: number = window.innerHeight;
              let kbHeight = viewportHeight / 2;      
              this.logger.info(`viewportHeight: ${viewportHeight}`);
              const focusedElement = document.activeElement;
              if (!focusedElement) {
                this.logger.info('WindowsKeyboardService.onWindowsKeyboardUp: Could not get focused input');
                return;
              }
    
              let inputFieldOffsetFromBottomViewPort: number = viewportHeight - focusedElement.getBoundingClientRect().bottom;
              let inputScrollPixels = kbHeight - inputFieldOffsetFromBottomViewPort;
    
              const ionApp = document.getElementsByTagName("ion-app")[0];
              this.logger.info(ionApp ? "got app" : "not got app");
    
              // Set margin to give space for native keyboard.
              ionApp.style["margin-bottom"] = kbHeight.toString() + "px";
    
              // But this diminishes ion-content and may hide the input field...
              if (inputScrollPixels > 0) {
                const content = document.getElementsByTagName('ion-content');
                if (!content || content.length == 0)
                  return;
    
                const topMostContent = content[content.length - 1];
                setTimeout(async () => {
                  let ionScroll = await topMostContent.getScrollElement();
                  ionScroll.animate({
                    scrollTop: ionScroll.scrollTop + inputScrollPixels
                  }, 300);
                }, 300); // Matches scroll animation from css.         
              }
            } catch (error) {
              this.logger.error(`WindowsKeyboardService.onWindowKeyboardUp: ${error}`);
            }
          }
    
          /**
          * Raised when a Windows soft keyboard is closed 
          */
          private onWindowsKeyboardClose(): void {
            try {
              this.logger.info("WindowsKeyboardService.onWindowKeyboardClose");
              const ionApp = document.getElementsByTagName("ion-app")[0];      
              ionApp.style["margin-bottom"] = "0";
            } catch (error) {
              this.logger.error(`WindowsKeyboardService.onWindowKeyboardClose: ${error}`);
            }
          }
        }
    

    isWindows 有以下...

    public static async isWindows(): Promise<boolean> {
      await Utils.platform.ready();     
      const result = window.cordova != undefined && window.cordova.platformId == "windows";
      return result;
    }
    

    我称它为如下形式的主要应用程序组件..

    public async ngAfterViewInit(): Promise<void> {
      try {
        this.logger.info('AppComponent: ngAfterViewInit');
        this.windowsKeyboardService.hookupKeyboardHandlers();
      } catch (error) {
        this.logger.error(`AppComponent: ngAfterViewInit: ${error}`);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-06-22
      • 2011-08-08
      • 1970-01-01
      • 2015-11-02
      • 2017-09-07
      • 1970-01-01
      • 2011-06-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多