前言
当使用基于触摸方式的链表视图时,默认提供的视图已经足够使用。在使用键盘甚至仅仅通过方向键选择一个元素的场景下,需要有标识当前选中元素的机制。在QML中,这即是高亮。
高亮代理
视图支持设置一个当前视图中显示代理元素中的高亮代理。它是一个附件的代理元素,这个元素仅仅只实例化一次,并移动到与当前元素相同的位置。
在下面例子的演示中,有两个属性来完成这个工作。首先是focus属性设置为true,它设置链表视图能够获得键盘焦点。然后是highlight属性,指出使用的高亮代理元素。高亮代理元素的x,y与height属性由当前元素指定。如果宽度没有特别指定,当前元素的宽度也可以用于高亮代理元素。
在下面的例子中,ListView.view.width属性被绑定用于高亮元素的宽度。关于代理元素的绑定属性将在后面介绍,但是只需知道相同的绑定属性也可以用于高亮代理元素。
import QtQuick 2.3
import QtQuick.Window 2.2
Window {
id: root
visible: true
width: 640
height: 480
color: "white"
ListView {
anchors.fill: parent
anchors.margins: 20
clip: true
model: 100
delegate: numberDelegate
spacing: 5
orientation: ListView.Horizontal
highlight: highlightComponent
focus: true
}
Component {
id: numberDelegate
Item {
width: 100
height: 100
//color: "lightGreen"
Text {
anchors.centerIn: parent
font.pixelSize: 10
text: index
}
}
}
Component {
id: highlightComponent
Rectangle {
width: ListView.view.width
color: "Green"
}
}
}
运行效果如下:
当使用高亮与链表视图结合时,一些属性可以用来控制它的行为。highlightRangeMode控制了高亮如何影响视图中当前的显示。默认设置ListView.NoHighLightRange表示高亮与视图中的元素距离不相关。
ListView.StrictlyEnforceRange确保了高亮始终可见,如果某个动作尝试将高亮移出当前视图可见范围,当前元素将会自动切换,确保了高亮始终可见。
ListView.ApplyRange尝试保持高亮代理始终可见,但是不会强制切换当前元素始终可见。如果在需要的情况下高亮代理允许被移出当前视图。
在默认配置下,视图负责高亮移动到指定位置,移动的速度与大小的改变能够被控制,使用一个速度值或者一个动作持续时间来完成它。这些属性包括highlightMoveSpeed、highlightMoveDuration、highlightResizeSpeed和highlightResizeDuration。默认下速度被设置为每秒400像素,动作持续时间为-1,表明速度和距离控制了动作的持续时间。如果速度与动作持续时间都被设置,动画将会采用速度较快的结果完成。
为了更加详细的控制高亮的移动,highlightFollowCurrentItem属性设置为false。这意味着视图将不再负责高亮代理的移动。取而代之可以通过一个行为或者一个动画来控制它。
在下面的例子中,高亮代理的y坐标属性与ListView.view.currentItem.y属性绑定。这确保了高亮始终跟随当前元素。然而,由于我们没有让视图来移动这个高亮代理,我们需要控制这个元素如何移动,通过Behavior on y来完成这个操作,在下面的例子中,移动分为三步完成:淡出,移动,淡入。注意怎样使用SequentialAnimation和PropertyAnimation元素与NumberAnimation结合创建更加复杂的移动效果。
import QtQuick 2.3
import QtQuick.Window 2.2
Window {
id: root
visible: true
width: 640
height: 480
color: "white"
ListView {
anchors.fill: parent
anchors.margins: 20
clip: true
model: 100
delegate: numberDelegate
spacing: 5
highlight: highlightComponent
focus: true
}
Component {
id: numberDelegate
Item {
width: 100
height: 100
Text {
anchors.centerIn: parent
font.pixelSize: 10
text: index
}
}
}
Component {
id: highlightComponent
Item {
width: ListView.view.width
height: ListView.view.currentItem.height
y: ListView.view.currentItem.y
Behavior on y {
SequentialAnimation {
PropertyAnimation { target: highlightRectangle }
NumberAnimation { duration: 1 }
PropertyAction { target: highlightRectangle }
}
}
Rectangle {
id: highlightRectangle
anchors.fill: parent
color: "lightGreen"
}
}
}
}