可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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); } } }