QML实现类iPhone联系人索引栏及滚动Section文本不更新问题求助
Hey there! I see you're trying to replicate that handy iPhone-style scroll indicator that shows the current section as you scroll, but your label's stuck on "A". Let's break down what's going wrong and fix it.
The Root of the Problem
Your topItem and topItemFix properties are only evaluated once when the Label is created—they don't update as the ListView scrolls. That means even when you scroll to a new section, the Label is still referencing the first item from when the component loaded.
Additionally, itemAt(0, cView.contentY) isn't the right way to get the first visible item. The itemAt() method takes x/y coordinates relative to the ListView's content, not the viewport.
The Fix
We need to make sure we're always grabbing the first visible item in the ListView, and updating that reference whenever the scroll position changes. Here are two solid approaches:
Approach 1: Use visibleItems (Cleanest)
ListView has a visibleItems property that returns an array of currently visible items. We can use this to get the first visible item and its section directly:
Label { anchors.centerIn: parent color: "White" font.bold: true font.pixelSize: 40 // Get the first visible item's section, or fallback to empty if none text: cView.visibleItems.length > 0 ? cView.visibleItems[0].ListView.section : "" }
Approach 2: Listen to Scroll Events
If you need more control, you can explicitly update the current section whenever the ListView's content position changes:
Label { anchors.centerIn: parent color: "White" font.bold: true font.pixelSize: 40 property string currentSection: "" // Update section when ListView scrolls Connections { target: cView function onContentYChanged() { if (cView.visibleItems.length > 0) { currentSection = cView.visibleItems[0].ListView.section } else { currentSection = "" } } } text: currentSection }
Bonus: Tweak the Indicator Position
Your current y-position formula for bigRect might be off. Here's a more reliable way to center the indicator on the scroll handle:
y: scrollBar.position * scrollBar.height - bigRect.height/2
This ensures the indicator stays centered over the scroll thumb as you drag it.
Full Modified ScrollBar Code
Putting it all together, your ScrollBar should look like this:
ScrollBar.vertical: ScrollBar { id: scrollBar Rectangle { id: bigRect visible: scrollBar.pressed color: "#1976D2" width: 96 height: width radius: width/2 x: -width - 16 // Centered over scroll thumb y: scrollBar.position * scrollBar.height - height/2 z:4 Rectangle { width: parent.width/2 height: parent.height/2 x: width y: height color: parent.color } Label { anchors.centerIn: parent color: "White" font.bold: true font.pixelSize: 40 text: cView.visibleItems.length > 0 ? cView.visibleItems[0].ListView.section : "" } } }
Why This Works
visibleItemsautomatically updates as the ListView scrolls, so we always get the latest first visible item.- The section property of that item (
ListView.section) gives us the correct current section character.
Give this a try—it should update the label to match the current section as you scroll!
内容的提问来源于stack exchange,提问作者sid

