Horizontale Listenansicht in der vertikalen Listenansicht in qml
Frage
Ich möchte, dass eine horizontale listView als Delegat für eine andere veritcal listView funktioniert. Ich habe den folgenden Code geschrieben:
import Qt 4.7
Item {
id:main
width: 360
height: 640
Component{
id:myDelegate
ListView{
id:list2
spacing: 5
width:list.width
height:list.height/3
interactive: true
orientation: ListView.Horizontal
model: ListModel {
ListElement {
name: "Bill Smith"
number: "555 3264"
}
ListElement {
name: "John Brown"
number: "555 8426"
}
ListElement {
name: "Sam Wise"
number: "555 0473"
}
ListElement {
name: "Sam Wise"
number: "555 0473"
}
ListElement {
name: "Sam Wise"
number: "555 0473"
}
}
delegate: Text{text:name
width: main.width/3}
focus: true
MouseArea {
anchors.fill: parent
onClicked: {
ListView.list2.currentIndex = ListView.list2.indexAt(mouseX, mouseY)
}
}
}
}
ListView {
id: list
clip: true
spacing: 5
anchors.fill: parent
orientation: ListView.Vertical
model: Model{}
delegate:myDelegate
// highlight: Rectangle {
// width: list.currentItem.width
// color: "lightsteelblue"
// radius: 5
// }
focus: true
MouseArea {
anchors.fill: parent
onClicked: {
list.currentIndex = list.indexAt(mouseX, mouseY)
}
}
}
}
Die vertikale Listenansicht scrollt gut, die horizontale jedoch nicht. Irgendeine Hilfe? Danke
Lösung
Ich habe es einmal versucht und es hat nicht funktioniert. Die äußere Liste behandelt alle Ereignisse.Die Lösung bestand darin, zusätzlich zu den ListViews ein Flickable zu haben und den Inhalt X der horizontalen und den Inhalt Y der vertikalen Listen in Inhalt X und den Inhalt Y des Flickable zu verankern.
Ein halb vollständiger Code, der das Prinzip zeigt:
Item {
ListView {
anchors.fill: parent
clip: true
orientation: ListView.Vertical
interactive: false
contentY: listController.contentY
delegate: ListView {
orientation: ListView.Horizontal
interactive: false
contentX: listController.contentX
}
}
Flickable {
id: listController
anchors.fill: parent
contentHeight: vert.contentHeight
contentWidth: horizontalElement.width
}
}
Andere Tipps
Ich habe diese Lösung auf dem Simulator ausprobiert und sie hat funktioniert.
import QtQuick 1.1
import com.nokia.symbian 1.1
Page {
id: mainPage
anchors.fill: parent
ListModel {
id: colorsModel
ListElement {
colorCode: "red"
}
ListElement {
colorCode: "green"
}
ListElement {
colorCode: "blue"
}
ListElement {
colorCode: "orange"
}
ListElement {
colorCode: "white"
}
ListElement {
colorCode: "purple"
}
ListElement {
colorCode: "gray"
}
ListElement {
colorCode: "yellow"
}
ListElement {
colorCode: "purple"
}
}
ListView {
anchors.fill: parent
model: 30
spacing: 20
cacheBuffer: 200 // in pixels
delegate:
ListView {
width: parent.width;
height: 50;
spacing: 20
model: colorsModel
orientation: ListView.Horizontal
delegate:
Rectangle {
color: colorCode
width: 50
height: 50
MouseArea {
anchors.fill: parent
onClicked: {
console.log(colorCode + " clicked");
}
}
}
}
}
}
In Ihrer vertikalen Listenansicht befindet sich ein generischer Codetagcode, der alle Ereignisse in Ihre horizontale Listenansicht stiehlt.In QML wird empfohlen, alle MouseArea
-Komponenten in den Delegaten aufzunehmen.
Verwenden Sie anstelle der MouseArea
-Methode auch die indexAt(mouseX,mouseY)
-Eigenschaft, die allen Delegaten zur Verfügung steht.
Verwenden Sie index
, um das Mausereignis vom MouseArea
des Listendelegierten zum MouseArea
des Listendelegierten zu übertragen.
Item {
id:main
width: 360
height: 640
Component{
id:myDelegate
ListView{
id:list2
spacing: 5
width:list.width
height:list.height/3
interactive: true
orientation: ListView.Horizontal
model: ListModel {
ListElement {
name: "Bill Smith"
number: "555 3264"
}
ListElement {
name: "John Brown"
number: "555 8426"
}
ListElement {
name: "Sam Wise"
number: "555 0473"
}
ListElement {
name: "Sam Wise"
number: "555 0473"
}
ListElement {
name: "Sam Wise"
number: "555 0473"
}
}
delegate: Text {
text:name
width: main.width/3}
focus: true
MouseArea {
anchors.fill: parent
onClicked: {
list2.currentIndex = index;
}
}
}
MouseArea {
anchors.fill: parent
onClicked: {
list2.ListView.view.currentIndex = index;
mouse.accepted = false;
}
}
}
ListView {
id: list
clip: true
spacing: 5
anchors.fill: parent
orientation: ListView.Vertical
model: Model{}
delegate:myDelegate
focus: true
}
}
Mit der Eigenschaft z
können äußere Listen zuerst Mausereignisse verarbeiten.
ListView {
z: 100 // put whatever you want or need
delegate: ListView {
z: 1000 // put whatever is above 100
}
}
Oder noch besser:
ListView {
delegate: ListView {
z: parent.z + 1
}
}
Ich bin mir jedoch nicht ganz sicher, ob dies ein zuverlässiger und korrekter Weg ist.