Martin Larsen Active Member Licensed User Longtime User Feb 18, 2020 #1 I have a problem with the soft keyboard hiding input fields in webviews. I have tried the solution in this post but it works "too well" so to speak. It always pushes the webview up, thus hiding fields in the top that would not normally be covered by the keyboard. I have attached an example loading the Register page from this forum. It works fine for the email and password fields. The webview is pushed upwards so you can see the fields while entering. However, the username fields is pushed out of sight as shown on screenshot #2. How can this problem be solved? Attachments webview.zip webview.zip 8.9 KB · Views: 837
I have a problem with the soft keyboard hiding input fields in webviews. I have tried the solution in this post but it works "too well" so to speak. It always pushes the webview up, thus hiding fields in the top that would not normally be covered by the keyboard. I have attached an example loading the Register page from this forum. It works fine for the email and password fields. The webview is pushed upwards so you can see the fields while entering. However, the username fields is pushed out of sight as shown on screenshot #2. How can this problem be solved?
JohnC Expert Licensed User Longtime User Feb 18, 2020 #2 There is not a lot you can do because webview always tries to make sure that whatever input item that currently has "focus" is clearly visible in webview. And in this case it looks like the focus is on the captcha checkbox and that is why it shifted up the page so make sure that the entire captcha item is visible. Because if the captcha checkbox is suppose to have focus, but the form was shifted any lower (to make the "Email" editextbox fully visible), then the keyboard will be chopping off the bottom of the captcha checkbox. To access the Email field, the user would simply scroll the page down until it is visible. Also, keep in mind that other devices with different size screens and/or DPI might be able to very well display the entire form even when the keyboard is shown because those devices have a larger screen. This shifting up of the page "functionality" is by design to make sure that all devices can access all fields of a form when the keyboard is displayed. Upvote 0
There is not a lot you can do because webview always tries to make sure that whatever input item that currently has "focus" is clearly visible in webview. And in this case it looks like the focus is on the captcha checkbox and that is why it shifted up the page so make sure that the entire captcha item is visible. Because if the captcha checkbox is suppose to have focus, but the form was shifted any lower (to make the "Email" editextbox fully visible), then the keyboard will be chopping off the bottom of the captcha checkbox. To access the Email field, the user would simply scroll the page down until it is visible. Also, keep in mind that other devices with different size screens and/or DPI might be able to very well display the entire form even when the keyboard is shown because those devices have a larger screen. This shifting up of the page "functionality" is by design to make sure that all devices can access all fields of a form when the keyboard is displayed.
Martin Larsen Active Member Licensed User Longtime User Feb 18, 2020 #3 I examined it further and I don't think it has anything to do with what field has the focus. I just choose the register page as an example, it happens on all pages with text input fields. Upvote 0
I examined it further and I don't think it has anything to do with what field has the focus. I just choose the register page as an example, it happens on all pages with text input fields.
JohnC Expert Licensed User Longtime User Feb 18, 2020 #4 Use webviewextras and run some javascript to force webview to scroll to the top of the page when you need it to.. First add the chromeclient and enable javascript in webview: B4X: Copy wve.addWebChromeClient(wv, "WVE") wv.JavaScriptEnabled = True Then you can inject/run the below javascript anytime you need the page to scroll to the top: B4X: Copy wve.executeJavascript(wv, "window.scrollTo(0, 0);" For example, you can run the above javascript the first time the keyboard is shown on a particular page. NOTE: You don't want to run this code EVERY time the keyboard is shown on the same page because the user could be working on a text field at the bottom of the page and you don't want the page to suddenly jump to the top when the keyboard appears because it will annoy the user. So, just use the code when it's appropriate. Last edited: Feb 18, 2020 Upvote 0
Use webviewextras and run some javascript to force webview to scroll to the top of the page when you need it to.. First add the chromeclient and enable javascript in webview: B4X: Copy wve.addWebChromeClient(wv, "WVE") wv.JavaScriptEnabled = True Then you can inject/run the below javascript anytime you need the page to scroll to the top: B4X: Copy wve.executeJavascript(wv, "window.scrollTo(0, 0);" For example, you can run the above javascript the first time the keyboard is shown on a particular page. NOTE: You don't want to run this code EVERY time the keyboard is shown on the same page because the user could be working on a text field at the bottom of the page and you don't want the page to suddenly jump to the top when the keyboard appears because it will annoy the user. So, just use the code when it's appropriate.
Martin Larsen Active Member Licensed User Longtime User Feb 19, 2020 #5 I have thought of something similar. The main problem is to know when to scroll the page or change the height of webview. I am experimenting with a callback from the webpage when an input field gets the focus. Upvote 0
I have thought of something similar. The main problem is to know when to scroll the page or change the height of webview. I am experimenting with a callback from the webpage when an input field gets the focus.
JohnC Expert Licensed User Longtime User Feb 19, 2020 #6 I might be misunderstanding your issue, but please keep in mind that webview will *automatically* scroll the page to make sure that the input item is visible even when the keyboard is displayed (if you are managing the size of webview properly). So, I guess my next question is how are you resizing webview when the keyboard appears and disappears? It should be similar to this: B4X: Copy Sub IME_HeightChanged(NewHeight As Int, OldHeight As Int) wv.Height = NewHeight End Sub (the above code assumes that webview is full screen) Basically, you should NOT be modifying the .Top property of webview, but instead modify the height of webview depending on if the keyboard is displayed or not. This way when webview gets "crushed" it will allow scrolling the page up or down to make sure the desired input field can be made displayed even in the reduce vertical window space when the keyboard is showing. Last edited: Feb 19, 2020 Upvote 0
I might be misunderstanding your issue, but please keep in mind that webview will *automatically* scroll the page to make sure that the input item is visible even when the keyboard is displayed (if you are managing the size of webview properly). So, I guess my next question is how are you resizing webview when the keyboard appears and disappears? It should be similar to this: B4X: Copy Sub IME_HeightChanged(NewHeight As Int, OldHeight As Int) wv.Height = NewHeight End Sub (the above code assumes that webview is full screen) Basically, you should NOT be modifying the .Top property of webview, but instead modify the height of webview depending on if the keyboard is displayed or not. This way when webview gets "crushed" it will allow scrolling the page up or down to make sure the desired input field can be made displayed even in the reduce vertical window space when the keyboard is showing.
JohnC Expert Licensed User Longtime User Feb 19, 2020 #7 Ok, I just took at look at your code and figured out what is wrong. First, you might want to use the anchors more efficiently for the webview by setting both anchors to full horizontal and full vertical (right now you are only anchoring left and top) and remove the below two lines from the "General Script" (Your code does the same thing, but anchors make it so much easier to do it): B4X: Copy WebView1.SetLeftAndRight(0%x,100%x) WebView1.SetTopAndBottom(0%y,100%y) Second, change the IME_HeightChanged code to this: B4X: Copy Sub IME_HeightChanged(NewHeight As Int, OldHeight As Int) WebView1.Height = NewHeight End Sub Last edited: Feb 19, 2020 Upvote 0
Ok, I just took at look at your code and figured out what is wrong. First, you might want to use the anchors more efficiently for the webview by setting both anchors to full horizontal and full vertical (right now you are only anchoring left and top) and remove the below two lines from the "General Script" (Your code does the same thing, but anchors make it so much easier to do it): B4X: Copy WebView1.SetLeftAndRight(0%x,100%x) WebView1.SetTopAndBottom(0%y,100%y) Second, change the IME_HeightChanged code to this: B4X: Copy Sub IME_HeightChanged(NewHeight As Int, OldHeight As Int) WebView1.Height = NewHeight End Sub
Martin Larsen Active Member Licensed User Longtime User Feb 19, 2020 #8 JohnC said: First, you might want to use the anchors more efficiently for the webview by setting both anchors to full horizontal and full vertical Click to expand... I must admit that I just modified one of the example apps in the B4A folder! I didn't even look at the layout That said,I really like designer scripts but in this case I fully agree: using anchors is much more straightforward. JohnC said: Second, change the IME_Height code to this: Click to expand... Wow, that was simple! I was taking the code from Erel's post thinking that it would apply to a webview too. But alas, no! I was beginning to think I had to go the javascript way with a callback to a B4A function to calculate the new position! Actually, just before your nice post I ended up with this line of Javascript: B4X: Copy ($(window).height() - $("input").offset().top - $("input").outerHeight(true) + $(window).scrollTop()) / $(window).height() This calculates the bottom of the input field as a fraction of the total height of the webview which can then be used to adjust the new TOP. Thankfully I didn't get to implement it in B4A before you post arrived. Your solution is so much simpler and better! Thanks! Upvote 0
JohnC said: First, you might want to use the anchors more efficiently for the webview by setting both anchors to full horizontal and full vertical Click to expand... I must admit that I just modified one of the example apps in the B4A folder! I didn't even look at the layout That said,I really like designer scripts but in this case I fully agree: using anchors is much more straightforward. JohnC said: Second, change the IME_Height code to this: Click to expand... Wow, that was simple! I was taking the code from Erel's post thinking that it would apply to a webview too. But alas, no! I was beginning to think I had to go the javascript way with a callback to a B4A function to calculate the new position! Actually, just before your nice post I ended up with this line of Javascript: B4X: Copy ($(window).height() - $("input").offset().top - $("input").outerHeight(true) + $(window).scrollTop()) / $(window).height() This calculates the bottom of the input field as a fraction of the total height of the webview which can then be used to adjust the new TOP. Thankfully I didn't get to implement it in B4A before you post arrived. Your solution is so much simpler and better! Thanks!