Search code examples
listviewtitaniumappcelerator-titanium

Titanium Android need to scroll the page when keyboard is visible


When I click on a textfield a keyboard appears. However, this slides all the content of the window upwards. Can you make the keyboard go over the window without scrolling content?


Solution

  • Background

    I highly recommend reading the official Android docs about Handling Input Method Visibility which mentions:

    When the input method appears on the screen, it reduces the amount of space available for your app's UI. The system makes a decision as to how it should adjust the visible portion of your UI, but it might not get it right. To ensure the best behavior for your app, you should specify how you'd like the system to display your UI in the remaining space.

    In other words, when the keyboard comes up, it can change the way your view looks, depending on a number of factors.

    One of those factors is windowSoftInputMode as described in the following:

    These are the options for windowSoftInputMode...

    The following options only affect if the keyboard pops up or not when the window is in focus and not the items in the view:

    • SOFT_INPUT_STATE_ALWAYS_HIDDEN: Always hide the soft input area (ie software keyboard) when the current heavyweight window receives focus.
    • SOFT_INPUT_STATE_ALWAYS_VISIBLE: Always show the soft input area (ie software keyboard) when the current heavyweight window receives focus.
    • SOFT_INPUT_STATE_HIDDEN: Attempt to hide the soft input area (ie software keyboard) when the current heavyweight window receives focus. Basically this stops the keyboard from automatically poping up when the windows open when a input is present.
    • SOFT_INPUT_STATE_VISIBLE: Attempt to show the soft input area (ie software keyboard) when the current heavyweight window receives focus.
    • SOFT_INPUT_STATE_UNSPECIFIED: Use the system-default behavior to determine whether to show the soft input area (ie software keyboard) when the current heavyweight window receives focus.

    The following options is the ones you will be most interested in as they relate to how the view should react upon the keyboard opening:

    • SOFT_INPUT_ADJUST_PAN: Pan the current heavyweight window when the input method (ie software keyboard) is shown, to ensure that its contents are not obscured.
    • SOFT_INPUT_ADJUST_RESIZE: Resize the current heavyweight window when the input method (ie software keyboard) is shown, to ensure that its contents are not obscured.
    • SOFT_INPUT_ADJUST_UNSPECIFIED: Use the system-default behaviour to determine how the soft input area (ie software keyboard) is accommodated by the current heavyweight window when it receives focus (default.) Depends on the AndroidManifest.xml setting if defined or system-default otherwise to determine how to accommodate the soft keyboard when visible.

    Note you can combine options like so:

    win.windowSoftInputMode = Ti.UI.Android.SOFT_INPUT_STATE_ALWAYS_VISIBLE | Ti.UI.Android.SOFT_INPUT_ADJUST_PAN;
    

    Reason Items are being Shifted

    The reason all your items are being shifted is because the window is using: SOFT_INPUT_ADJUST_RESIZE and something is being positioned vertically using percentages. For example:

    <View height="100%">
        <Label top="10">Top label</Label>
        <Label>Centre label</Label>
        <Label bottom="10">Bottom label</Label>
    </View>
    

    This means when the keyboard goes up, the overall height of the view gets reduced, thus shifting all the items up.

    Solutions

    There is 2 main solutions to this issue.

    Solution 1 Make the window use SOFT_INPUT_ADJUST_PAN. This doesn't reduce the overall height of the app, but instead pans to the relevant part of the screen. Therefore, this should stop all the items shifting up.

    Solution 2 Make sure the position of items is not dependent on the device height (which can change).

    e.g.

    <View height="500px">
        ...
    </View>
    

    OR

    <View height="Titanium.UI.SIZE">
        ....
    </View>
    

    That way, when the keyboard goes up, the view does not reduce in height and the keyboard simply goes over the content instead of shifting items up. However you now risk the chance of certain things cropped off the screen, if the device height is less than 500px. Also when the keyboard is up, you have even less space, meaning even more things can get cropped off.

    A solution to this is to use a scrollable view. e.g.:

    <ScrollableView height="500px">
        ...
    </ScrollableView>
    

    or

    <ScrollableView height="Titanium.UI.SIZE">
        ...
    </ScrollableView>
    

    Now the user can still scroll to see other parts of the screen, if the device screen is too small. The user can even scroll when the keyboard is up.