qtlistviewqmloverlappingswipeview

QML ListView, SwipeView etc. - avoid overlapping of other UI components


I'm trying to avoid this annoying overlapping that both SideView and ListView seem to fancy. Here is an example which demonstrates the issue:

Note: Look at the green rectangle on the left when you swipe the SwipeView and also the tabs when you scroll down the ListView

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QLatin1String("qrc:/main.qml")));

    return app.exec();
}

main.qml

import QtQuick 2.7
import QtQuick.Window 2.0
import QtQuick.Controls 2.0
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.2

Window {
    id: window
    visible: true
    width: 600
    height: 480
    title: "Demo"
    RowLayout {
        id: layoutTopLevel
        anchors.fill: parent
        spacing: 0
        Rectangle {
            id: sidebarView
            Layout.preferredWidth: layoutTopLevel.width * .3
            Layout.fillHeight: true
            color: "#453"
            border.width: 1
        }
        ColumnLayout {
            id: sideViewLayout
            spacing: 0
            SwipeView {
                id: sideView
                currentIndex: sideViewPageIndicator.currentIndex
                Layout.fillWidth: true
                Layout.preferredHeight: layoutTopLevel.height * .9
                Page {
                    id: page1
                    header: Text {
                        text: "Page 1"
                        horizontalAlignment: Text.AlignHCenter
                        font.pixelSize: 20
                    }
                }
                Page {
                    id: page2
                    header: Text {
                        text: "Page 2"
                        horizontalAlignment: Text.AlignHCenter
                        font.pixelSize: 20
                    }

                    TabView {
                        id: page2TabView
                        width: parent.width
                        height: parent.height
                        anchors.margins: 4
                        tabPosition: Qt.BottomEdge

                        Tab {
                            title: qsTr("Tab 1")
                        }
                        Tab {
                            title: qsTr("Tab 2")
                            ColumnLayout {
                                Text {
                                    text: "Text 1"
                                    Layout.alignment: Qt.AlignCenter
                                }
                                Text {
                                    text: "Text 2"
                                    Layout.alignment: Qt.AlignCenter
                                }

                                ListView {
                                    width: parent.width
                                    height: parent.height
                                    model: ListModel {
                                        ListElement {
                                            name: "Element 1"
                                        }
                                        ListElement {
                                            name: "Element 2"
                                        }
                                        ListElement {
                                            name: "Element 3"
                                        }
                                        ListElement {
                                            name: "Element 4"
                                        }
                                        ListElement {
                                            name: "Element 5"
                                        }
                                        ListElement {
                                            name: "Element 6"
                                        }
                                    }

                                    delegate: Text {
                                        text: name
                                    }
                                }
                            }
                        }

                        style: TabViewStyle {
                            tabsAlignment: Qt.AlignHCenter
                            frameOverlap: 1
                            tab: Rectangle {
                                border.width: styleData.selected
                                implicitWidth: Math.max(text.width + 4, 80)
                                implicitHeight: 20
                                radius: 10
                                Text {
                                    id: text
                                    anchors.centerIn: parent
                                    text: styleData.title
                                    color: styleData.selected ? "white" : "black"
                                }

                                color: styleData.selected ? "#654" : "white"
                            }
                            frame: Rectangle {
                                color: "white"
                            }
                        }
                    }
                }
            }
            PageIndicator {
                id: sideViewPageIndicator
                count: sideView.count
                interactive: true
                anchors.bottom: sideView.bottom
                anchors.bottomMargin: -45
                anchors.horizontalCenter: parent.horizontalCenter

                delegate: Rectangle {
                    height: 30
                    width: 30
                    antialiasing: true
                    color: "#654"
                    radius: 10

                    opacity: index === sideView.currentIndex ? 0.95 : pressed ? 0.7 : 0.45
                    Behavior on opacity {
                        OpacityAnimator {
                            duration: 100
                        }
                    }
                }
            }
        }
    }
}

Solution

  • Use clip: true

    Which clips the content which goes out of its boundaries.