Can webpage be aware of android virtual keyboard
Asked Answered
C

3

9

I have web page with jquery terminal and hidden textarea (that trigger Android Virtual keyboard), I can type characters but when I enter few commands the content is hidden behind Virtual Keyboard. Terminal content is scrolling to bottom because when I type some more command it's scrolling. When I use hardware keybaord in my phone scrolling is right (touch scroll is not working yet).

I added this CSS

.terminal textarea { top: 0; width:0; margin-left: -8px; pointer-events: none; }

to prevoius

.terminal .clipboard {
    position: absolute;
    bottom: 0;
    left: 0;
    opacity: 0.01;
    filter: alpha(opacity = 0.01);
    filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.01);
    width: 2px;
}
.cmd > .clipboard {
    position: fixed;
}

and have this code in plugin (textarea was used for clipboard).

 self.click(function() {
     self.find('textarea').focus();
 });

And my qestion is this: can javascript detect how big Virtual Keyboard is? Or maybe there is other way to change the size of the webpage so it's be only in visual part (not where keyboard is)? Or maybe something is wrong with my code, it was not designed to work on mobile. Does the size of the keyboard is always the same, even if user install different one?

Carnival answered 29/6, 2012 at 15:19 Comment(0)
C
3

From what I've seen, when the virtual keyboard pops up, the page is not resized (to fit the smaller view-area, visible with the virtual keyboard on). So this will not give your page a hint on whether the keyboard is up or not. And I don't really think there's another way of getting that info either.

You can make a setup where you look at the user agent, and if it's for an Android phone, when the user clicks various text input elements, you make some room at the bottom of the screen for the virtual keyboard.

For the size of the keyboard, the stock Android might have a standard size or ratio or percentage, but combined with the fact that there are a lot of Android mods out there plus the fact that there are multiple screen resolutions and screen ratios out there translates into not being able to have a fixed number for this (like keyboard is x pixels tall or y percent of screen estate). However, you can make a common sense assumption that it takes about half of the screen at the bottom.

So basically, using the user agent, screen resolution and the fact that the user has "clicked" on a text input field, you can get a decent idea of whether a virtual keyboard is displayed or not, and how much room to leave aside for it.

Coordination answered 8/3, 2013 at 8:51 Comment(4)
I don't understand why this is the accepted answer.. I know SO is a meritocracy, and I'm glad that it is, but I actually describe a way in which you can find out the size of the virtual keyboard (or better even: the size of the Activity's available screen space) in my answer. Moreover I also present some alternative thoughts on the implementation, because using stuff like "invisible views" to just get the keyboard up sounds a bit hacky to say the least. I couldn't care the least that mine is not the accepted answer, but now everybody that reads the question will, IMO, read an incorrect answer.Cartie
@Cartie Maybe because this addresses it as a webpage, rather than with java code for a native app? Read the title.Fall
If you read my answer again, you will see that although it includes "native" (java) code, the final purpose of this code is to pass the size of the visible window to the javascript code in your webview (using the loadUrl() method). The question was "can javascript detect how big Virtual Keyboard is?", and the short answer is "no". But it turns out you can get the requested size using java (native) code and pass it to javascript, and my answer explain how..Cartie
Aside: I think the trouble you have to go through to get this IME/Window size in javascript already shows that a different approach should be taken altogether, and for that reason alone I am happy to admit that my answer should not be implemented EVER :-) It was more of an afternoon exercise to see if it could be done, should you really want to..Cartie
C
5

1 You can use android:windowSoftInputMode attribute within the <activity> element in your Manifest.xml to select amongst various resizing strategies when the IME pops up. These include (not limited to):

adjustResize, which will resize your Activity's content view (and the WebView in it) to fit the remaining space.

adjustPan, which will leave the content view to fill the entire screen, partially occluded by the IME's Window.

Playing with these may already give you the behavior you are looking for.

2 Android's default behavior when it comes to scrolling a (Web)View when the IME pops up is that it tries to keep the cursor visible. In your case you are putting your cursor (or: focus) on a hidden view. This explains the weird behavior you are seeing and I think you would do well to change your implementation. Why are you not using a visible textarea in the first place? Your text will have to end up somewhere, right? And then Android will handle the focus/scroll automatically.

As a workaround: something you could try is to position your hidden view smarter and clear its contents from time to time, thereby dodging your scrolling issue. Of course the viability of this option depends on your exact use case.

3 This will be the answer to the question you are asking, but I am unsure how this will help you (maybe because of my inexperience with html):

To get the height of the WebView (which is Screen size - IME height) in your javascript do the following:

  • In your manifest, add the android:windowSoftInputMode="adjustResize" attribute to your element.
  • extend your outer layout like this:

    public class RelativeLayoutWithLayoutListener extends RelativeLayout {
    
    public interface LayoutListener {
        public void onLayout();
    }
    
    private LayoutListener mListener;
    
    public RelativeLayoutWithLayoutListener(Context context) {
        super(context);
    }
    
    public RelativeLayoutWithLayoutListener(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    
    public RelativeLayoutWithLayoutListener(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    public void setLayoutListener(LayoutListener aListener) {
        mListener = aListener;
    }
    
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (mListener != null) {
            mListener.onLayout();
        }
    }
    }
    
  • Swap out your old layout for the newly created one in your layout.xml file.

  • In your Activity code, do something like this:

    public class MainActivity extends Activity {
    
    private RelativeLayoutWithLayoutListener mMainLayout;
    
    private WebView mWebView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mMainLayout = (RelativeLayoutWithLayoutListener)findViewById(R.id.main_layout);
    
        mMainLayout.setLayoutListener(new LayoutListener() {
    
            @Override
            public void onLayout() {
                mWebView.loadUrl("javascript:setSize(" + mMainLayout.getWidth() + "," + mMainLayout.getHeight() + ")");             
            }
        });
    
        mWebView = (WebView)findViewById(R.id.webview);
    }
    }
    

Of course in the loadUrl() call you will have to call a javascript method you defined. You can of course also pass in the height of the IME if you do some calculations first.

Cartie answered 13/3, 2013 at 15:45 Comment(0)
C
3

From what I've seen, when the virtual keyboard pops up, the page is not resized (to fit the smaller view-area, visible with the virtual keyboard on). So this will not give your page a hint on whether the keyboard is up or not. And I don't really think there's another way of getting that info either.

You can make a setup where you look at the user agent, and if it's for an Android phone, when the user clicks various text input elements, you make some room at the bottom of the screen for the virtual keyboard.

For the size of the keyboard, the stock Android might have a standard size or ratio or percentage, but combined with the fact that there are a lot of Android mods out there plus the fact that there are multiple screen resolutions and screen ratios out there translates into not being able to have a fixed number for this (like keyboard is x pixels tall or y percent of screen estate). However, you can make a common sense assumption that it takes about half of the screen at the bottom.

So basically, using the user agent, screen resolution and the fact that the user has "clicked" on a text input field, you can get a decent idea of whether a virtual keyboard is displayed or not, and how much room to leave aside for it.

Coordination answered 8/3, 2013 at 8:51 Comment(4)
I don't understand why this is the accepted answer.. I know SO is a meritocracy, and I'm glad that it is, but I actually describe a way in which you can find out the size of the virtual keyboard (or better even: the size of the Activity's available screen space) in my answer. Moreover I also present some alternative thoughts on the implementation, because using stuff like "invisible views" to just get the keyboard up sounds a bit hacky to say the least. I couldn't care the least that mine is not the accepted answer, but now everybody that reads the question will, IMO, read an incorrect answer.Cartie
@Cartie Maybe because this addresses it as a webpage, rather than with java code for a native app? Read the title.Fall
If you read my answer again, you will see that although it includes "native" (java) code, the final purpose of this code is to pass the size of the visible window to the javascript code in your webview (using the loadUrl() method). The question was "can javascript detect how big Virtual Keyboard is?", and the short answer is "no". But it turns out you can get the requested size using java (native) code and pass it to javascript, and my answer explain how..Cartie
Aside: I think the trouble you have to go through to get this IME/Window size in javascript already shows that a different approach should be taken altogether, and for that reason alone I am happy to admit that my answer should not be implemented EVER :-) It was more of an afternoon exercise to see if it could be done, should you really want to..Cartie
C
0

If you looking for the way to keep the terminal content visible even when the keyboard pop, you doesn't need to know the keyboard size. The problem is in your "#shell" height. Try to open Developer Tools on Chrome (desktop) and resize your window. You'll see that the height of "#shell" div is always fit to device height, not the content area height. So, when the keyboard pop, the content will be on the backward of keyboard. To make it works, you should force your "#shell" height to fit to the content area. I try to modify the css and it's works properly in my android emulator. Also remove the touch-scroll js from your page, it's unnecessary. You can append this css code to your css file.

#shell {
    position: fixed !important;
    top: 0; left: 0;
    width: 100% !important; height: 100% !important;
    margin: 0 !important; padding: 0 !important;
    -webkit-transition: none !important;
    -webkit-transform: none !important;
    overflow-y: visible !important;
}

#shell .terminal-output, #shell .cmd {
    margin: 10px;
}

Hope this help. :)

Coombs answered 12/3, 2013 at 15:1 Comment(2)
It don't work on actual phone, when I don't use virtual keyboard scroll to bottom work when I hit enter but scrolling using finger don't work. When I remove position: fixed !important; top: 0; left: 0; scrolling using figer work but not scroll to bottom. And terminal is still below virtual keyboard.Carnival
So sorry, i don't have real android phone yet. But it works properly in both android simulator and ios simulator. I think what you have to do is remove all element position (both fixed or relative) and set the element display to block. Then set float: left; to the .terminal, .cmd. Finaly, add click and key event to focus to the input. Also do not hide any overflow. Thx.Coombs

© 2022 - 2024 — McMap. All rights reserved.