我正在尝试使用ListView实现5行集中式菜单。突出显示位置的文本需要大于其他菜单项,并且应该在滚动菜单时平滑过渡。理想情况下应该有3种不同的文字大小 - 中央最大,中央旁边的项目略小,外面的项目甚至更小,但中央项目的更大文本是可以的。
当菜单停止滚动时,如果大于屏幕宽度,则需要水平滚动集中项目。
这适用于具有用于菜单导航的旋转编码器的嵌入式设备。 setIndex()用于设置菜单位置。
以下代码在缓慢滚动时工作正常,但在滚动速度较快时会有点困惑。中央酒吧外面的物品有时会变大等等。
看起来像一个应该已经解决的问题,但我无法在任何地方找到一个例子。
这是代码 -
import QtQuick 1.1
// Menu
// 5 line menu, highlight bar centralised
Rectangle {
id: window
color: "#00000000"
property int numLines: 5
property alias menuIndex: listView.currentIndex
property int lineHeight: window.height/window.numLines
property alias model: listView.model
clip: true
function setIndex(iIndex) {
var displayedIndex = Math.round((listView.contentY/window.lineHeight + Math.floor(numLines/2)));
//console.log("MENU2: " + displayedIndex + " " + iIndex + " " + Math.abs(displayedIndex - iIndex));
// If we're too far behind current index jump straight to it rather than leaving it to smooth scroll
if (Math.abs(displayedIndex - iIndex) > 15)
listView.positionViewAtIndex(iIndex, ListView.Center);
listView.currentIndex = iIndex
}
function setItemSelected(bSelected) {
scrollingText.setItemSelected(bSelected);
}
// Define a delegate component. A component will be
// instantiated for each visible item in the list.
Component {
id: menuItemDelegate
Item {
id:wrapper
height: window.height/window.numLines
width: window.width
Text {id: wrapperText; text: menuText; width: window.width; height: window.height/window.numLines; font.pixelSize: (wrapper.height * 3)/4; color: "white"; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter}
states: [
State {
name: "Current"
when: wrapper.ListView.isCurrentItem
PropertyChanges { target: wrapper; scale: 1.0 }
PropertyChanges { target: scrollingText; currentText: menuText }
PropertyChanges { target: scrollingText; scrollStart: true }
},
State {
name: "NotCurrent"
when: wrapper.ListView.isCurrentItem == 0
PropertyChanges { target: wrapper; scale: 0.7 }
}
]
transitions: Transition {
ParallelAnimation
{
NumberAnimation { properties: "scale"; duration: 100 }
}
}
}
}
// Highlight bar
Image {id: highlightBar; y: 2 * window.lineHeight; height: lineHeight; width:window.width; source: "Menu_HighlightBar.png"; scale: 1; opacity:1}
// Scrolling text that pops up on top of highlight bar area
Menu2ScrollingText {id: scrollingText; x:0; z:1; y: 2 * window.lineHeight; height: lineHeight; width: window.width}
ListView {
id: listView
anchors.fill: window
//model: cppMenuModel
delegate: menuItemDelegate
highlight: Rectangle { color: "lightsteelblue"; opacity: 0 } // not visible
highlightFollowsCurrentItem: true
preferredHighlightBegin: highlightBar.y
preferredHighlightEnd: preferredHighlightBegin + window.lineHeight
highlightRangeMode: ListView.StrictlyEnforceRange
currentIndex: 0
}
}