Sencha Touch 2.1: Form Panel Keyboard hides active Textfield on Android

匿名 (未验证) 提交于 2019-12-03 02:45:02

问题:

When I tap a textfield at the bottom of the screen, the keyboard appears and hides the active element. On iOS, it works perfect.

I'm able to scroll the form, so the textfield is in the visible area, but that's not nice at all. Am I doing something wrong or is this a known bug as I have the same behaviour in this example from Sencha Touch itself: docs.sencha.com/touch/2-1/touch-build/examples/forms/

If on this form:

I tap in the textfield of "Bio", the keyboard hides the textfield, instead of scrolling the textfield up to have it visible while typing:

回答1:

This is definitively a known-issue, I've seen this many times on Android. The only thing you can try to do is listen for a focus event on the input field and then scroll to the element. You might have to play around with the right Y-value, which suits your situation best.

{     xtype: 'textareafield',     name: 'bio',     label: 'Bio',     maxRows: 10,     listeners: {         focus: function(comp, e, eopts) {             var ost = comp.element.dom.offsetTop;             this.getParent().getParent().getScrollable().getScroller().scrollTo(0, ost);         }     } }, 

This works for me. If you need any help implementing this, let me know!



回答2:

Less intrusive solution:

on Application launch method add the following lines:

launch: function() {     if (Ext.os.is.Android) { //maybe target more specific android versions.         Ext.Viewport.on('painted', function() {             Ext.Viewport.setHeight(window.innerHeight);         });     }     // ... rest of the launch method here } 

This works just fine on many cases I have been testing on. Both Cordova and Chrome implementations. You just need to take care, in case of Cordova/Phonegap app, that the fullscreen is set to false. (Tested on Cordova 3.5)



回答3:

The "Ext.Viewport.on('painted'"-solution gave me scrolling problem. The whole page could not be scrolled after orientation change, because viewport height would then be larger than window height. (Ext.Viewport.getHeight() will not be the same as Ext.Viewport.getWindowHeight() after orientation change.)

Made a work around using overidden input:

Create a file app/overrides/field/Input.js

Ext.define('myApp.overrides.field.Input', {   override: 'Ext.field.Input',    initialize: function() {     var me = this;      // Solves problem that screen keyboard hides current textfield     if (Ext.os.is.Android) {         this.element.on({             scope      : this,             tap        : 'onTap',         });     }      me.callParent();   },    onResize: function(input) {     var me = input;     //if input is not within window     //defer so that resize is finished before scroll     if(me.element.getY() + me.element.getHeight() > window.innerHeight) {         Ext.Function.defer(function() {             me.element.dom.scrollIntoView(false);         }, 100);     }   },    // Solves problem that screen keyboard hides current textfield in e.g. MyTimeRowForm   //old solution with Viewport.on('painted', gave scroll problem when changeing orientation   onTap: function(e) {     me = this;     window.addEventListener( "resize", function resizeWindow () {         me.onResize(me);         window.removeEventListener( "resize", resizeWindow, true );     }, true );   },    }); 

And add it to app.js

requires: ['myApp.overrides.field.Input'] 


回答4:

You may subscribe on show/hide events of keyboard and compensate input's offset. It's been tested on Android 4.2 & 4.4 (HTC One & Nexus 7).

if (Ext.os.is.Android4 && Ext.os.version.getMinor() >= 2) {     (function() {         var inputEl = null;         var onKeyboardShow = function() {             setTimeout(function() {                 if (!inputEl) {                     return;                 }                 var currentClientHeight = window.document.body.clientHeight;                 var elRect = inputEl.getBoundingClientRect();                 var elOffset = elRect.top + elRect.height;                 if (elOffset <= currentClientHeight) {                     return;                 }                 var offset = currentClientHeight - elOffset;                 setOffset(offset);             }, 100);         };         var onKeyboardHide = function() {             setOffset(0);         };         var setOffset = function(offset) {             var el = Ext.Viewport.innerElement.dom.childNodes[0];             if (el) {                 el.style.setProperty('top', offset + 'px');             }         };         document.addEventListener('deviceready', function() {             document.addEventListener("hidekeyboard", onKeyboardHide, false);             document.addEventListener("showkeyboard", onKeyboardShow, false);         }, false);         Ext.define('Ext.field.Input.override', {             override: 'Ext.field.Input',             onFocus: function(e){                 inputEl = e.target;                 this.callParent(arguments);             },             onBlur: function(e){                 inputEl = null;                 this.callParent(arguments);             }         })     })(); } 


回答5:

It worked better for me

{    xtype: 'passwordfield',    name: 'pass',    listeners: {       focus: function (comp, e, eopts) {         var contr = this;         setTimeout(function () {           if (Ext.os.is('Android')) {             var ost = comp.element.dom.offsetTop;             contr.getParent().getParent().getScrollable().getScroller().scrollTo(0, ost, true);           }         }, 400);       }    } } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!