QML item fixed positioning



  • The mobile devices move the elements up the the keyboard is called, but there are elements that stay in the same position when the device's keyboard appears like the images below.

    How can I keep a Qml item fixed in the same position when device's keyboard appears?

    I need that the Rectangle with id: principal stays fixed in the same position.

    import QtQuick 2.4
    import QtQuick.Window 2.2
    import QtQuick.Controls 1.3
    
    Window {
        visible: true
    
        property int larguraTela: 360
        property int alturaTela: 640
    
        width: larguraTela
        height: alturaTela
    
        maximumWidth: larguraTela
        maximumHeight: alturaTela
    
        minimumWidth: larguraTela
        minimumHeight: alturaTela
    
        title: "OverStatusBar"
    
        Rectangle {
            id: principal
    
            width: parent.width
            height: parent.height * 0.15
    
            anchors.top: parent.top
    
            color: "orange"
        }
    
        Rectangle {
    
            width: parent.width
            height: parent.height * 0.85
    
            anchors.top: principal.bottom
    
            clip: true
    
            Rectangle{
                id: retangulo1
    
                width: parent.width
                height: parent.height * 0.5
    
                anchors.top: parent.top
    
                color: "grey"
            }
    
            Rectangle {
                id: retangulo2
    
                width: parent.width
                height: parent.height * 0.5
    
                anchors.top: retangulo1.bottom
    
                color: "lightgrey"
    
                TextField {
                    id: campoTexto
    
                    width: parent.width * 0.7
                    height: parent.height * 0.20
    
                    anchors.centerIn: parent
    
                    inputMethodHints: Qt.ImhDigitsOnly
    
                }
            }
        }
    }
    

    enter image description here enter image description here



  • One option could be to reparent your Rectangle inside a Flickable so that you can set the flickable contentY property according to Textfield activeFocus.



  • Hello @Charby
    Could you give me an little example?



  • Actually I misunderstood your issue...
    Despite I now have a better understanding (If I am not wrong, you would like "principal" rectangle to remain always visible whatever is the visibilty of the virtual keyboard), I haven't been able to come up with a solution... so far I tried :

    • list itemusing an ApplicationWindow i.o Window and defining "Principal" as a toolbar of the application window
    • using a Flickable containing every items except Principal and change contentY depending of the text field focus.
    • define "Principal" as an overlay
    • ...
      but unfortunately, every attempts were unsatisfactory...I will continue tomorrow as this is really puzzling me now to understand what is going wrong.


  • Unfortunately I don't have a satisfactory solution and I am now running out of idea...the best workaround I found is to add an item at the bottom of the screen to reserve a fix height for the virtual keyboard.

    This hackish approach could have been improved by having the reserve item height to be null when the virtual keyboard is not visible but I haven't find a way to determine when the virtual keyboard shows up. Using activeFocus property of a TextField is not enough.



  • Thank you @Charby for all your effort to help me solving this. I will also keep trying a solution for this issue.



  • Hello @SGaist and @p3c0 !

    Any suggestion about this problem?



  • Mike Krus is mentionning this behavior on IOS in this lightning talk (at 43:17).
    It seems it is possible to counteract this default behavior by detecting before the keyboard show up if the TextField is below the last third of the screen and then move it up before the keyboard appear.
    That's basically what I tried to achieve yesterday :

    • a) embed the "content" inside a flickable
    • b) detect when the virtual keyboard show up
    • c) ensure the focus element y is above the keyboard, and if not use the flickable contentY to rise it.

    a) and c) can easily be managed, but I don't know how to be notified just before the VK shows up (thus before the application window gets offseted). So far I tried to watch the ActiveFocus change of the TextField but it is too late... Do you know another way to detect the keyboard ?



  • No I don't.

    I was reading some stuff here, and I figured out that what I want is something that works as the iOS navigation bar. There is any Type in Qml that can do that? I tried StackView, but it also moves up when the keyboard appears.



  • @benlau Hello!

    I have seen that you did a navigation bar like native in iOS. Could you help me with this?



  • Hello @Charby !

    Is possible to do it using the xCode (Objective C) navigation bar and, in android, jni to solve that?


  • Lifetime Qt Champion

    Hi,

    One way to track the keyboard visibility could be to use the QInputMethod::visible property.

    Hope it helps



  • @guidupas This could worth a try...but I guess the native navigation bar is still part of the application window so It should also be offseted outside of the screen/

    @SGaist Excellent !
    I think we can now achieve to get a satisfactory workaround...



  • I have something very hackish and begging for refinement but I think it is going into the right direction :

    • a flickable to offset the content :
    • when the keyboard appear :
      • offset the content to ensure the focus item is not below the keyboard
      • reset the keyboard

    There are several improvements area :

    • replace the timer by a better method and simplify the logic
    • offset the content only when needed (don't offset when the focus item is already above the keyboard when it appears)
    • embed this in a component having toolbar and content properties
    import QtQuick 2.4
    import QtQuick.Window 2.2
    import QtQuick.Controls 1.3
    Window {
        visible: true
        property int larguraTela: 360
        property int alturaTela: 640
        width: larguraTela
        height: alturaTela
        maximumWidth: larguraTela
        maximumHeight: alturaTela
        minimumWidth: larguraTela
        minimumHeight: alturaTela
        title: "OverStatusBar"
        Rectangle {
            id: principal
            width: parent.width
            height: parent.height * 0.15
            anchors.top: parent.top
            color: "orange"
        }
        Timer{
            id:resetKeyboard
            interval: 500
            onTriggered: {
                Qt.inputMethod.hide();
                Qt.inputMethod.show();
                unlock.restart();
            }
        }
        Timer{
            id:unlock
            interval: 500
    
            onTriggered: {
                flickable.updateSlideContent = true;
            }
        }
    
        Flickable{
            id:flickable
            width: parent.width
            height : slideContent ? parent.height * 0.5 : parent.height * 0.85
            anchors.top: principal.bottom
            clip: true
            contentHeight: parent.height * 0.85
            contentY : slideContent ? parent.height*0.35 : 0
    
            property bool updateSlideContent : true
            property bool slideContent : false
            property bool keyboardVisible : Qt.inputMethod.visible
            onKeyboardVisibleChanged: {
                if (updateSlideContent) {
                    slideContent = keyboardVisible;
                    if (keyboardVisible)
                    {
                        updateSlideContent = false;
                        resetKeyboard.restart();
                    }
                }
            }
    
            Rectangle {
    
                anchors.fill: parent
    
    
    
    
                Rectangle{
                    id: retangulo1
    
                    width: parent.width
                    height: parent.height * 0.5
    
                    anchors.top: parent.top
    
                    color: "grey"
                }
    
                Rectangle {
                    id: retangulo2
    
                    width: parent.width
                    height: parent.height * 0.5
    
                    anchors.top: retangulo1.bottom
    
                    color: "lightgrey"
    
                    TextField {
                        id: campoTexto
    
                        width: parent.width * 0.7
                        height: parent.height * 0.20
    
                        anchors.centerIn: parent
    
                        inputMethodHints: Qt.ImhDigitsOnly
    
                    }
                }
            }
    
        }
    }
    


  • Yes, but it is to much workaround.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.