看网上都是通过PathView来写,但是写出来的都是首位相连的效果,并不是想要的效果,而且又改不动(接触QML不长,无奈自己写),而我想要的效果是从左往右,一页显示三个,最中间的的图片放大 。
先看效果
先分析效果图 ,用ListView来实现 ,首先第一个view是显示在中间 ,所以要添加一个header,然后尾部也是要显示在中间 所以 ,尾部也添加一个view
ListView{
...
header: Item {
width: listView.width / 3
height: listView.height
}
footer: Item {
width: listView.width / 3
height: listView.height
}
...
}
为什么width是listView.width/3? 因为当前可视界面需要显示3个view,所以 宽度都设置成listView的 1/3 就好,如果需要显示
2个 除2就好了 依此类推。
ListView{
delegate: Item {
width: listView.width / 3
height: listView.height
...
}
...
}
delegate 也是跟 头尾一样宽度。
计算currentIndex,当选中的view 缩放,用到onMovementEnded
方法
onMovementEnded: {
var itemWidth = listView.width / 3;
var start = contentX + itemWidth;
var newIndex = Math.floor(start / itemWidth); // 向下取整 计算出 currentIndex
listView.currentIndex = newIndex;
}
说明
比较重要的属性
-
header
: 添加头部 -
footer
: 添加底部 -
snapMode
:滚动时的对齐方式 例如 ListView.SnapToItem 表示滚动时会自动对齐到最近的项。 -
boundsBehavior
: 边界行为,例如 Flickable.StopAtBounds 表示滚动到边界时停止。
重要方法
-
onMovementEnded
:表示移动结束
全部代码
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
visible: true
width: 1080
height: 700
title: qsTr("Hello World")
id: root
property int count: 6
property int current: 4
ListView {
id: listView
anchors.fill: parent
model: root.count
currentIndex: root.current
orientation: ListView.Horizontal
snapMode: ListView.SnapToItem
boundsBehavior: Flickable.StopAtBounds
property int lastContentX: 0
header: Item {
width: listView.width / 3
height: listView.height
}
footer: Item {
width: listView.width / 3
height: listView.height
}
delegate: Item {
width: listView.width / 3
height: listView.height
Image {
anchors.fill: parent
scale: listView.currentIndex === index ? 0.9 : 0.7 //缩放大小
fillMode: Image.PreserveAspectFit
// source: root.current=== index ? "qrc:/image/test.png" : "qrc:/image/test.png" // 可以判断显示不同图片
source: "qrc:/image/test.png"
// 看起来柔和点 添加动画
Behavior on scale {
NumberAnimation {
duration: 100
easing.type: Easing.InOutQuad
}
}
Text {
text: index+""
font.pixelSize: 32
}
}
}
onMovementEnded: {
var itemWidth = listView.width / 3;
var start = contentX + itemWidth;
var newIndex = Math.floor(start / itemWidth);
listView.currentIndex = newIndex;
}
// 看起来柔和点 添加动画
transitions: Transition {
NumberAnimation {
properties: "contentX"
duration: 100
easing.type: Easing.InOutQuad
}
}
}
Component.onCompleted: {
// 滚动到currentIndex
var itemWidth = listView.width / 3;
listView.contentX = (listView.currentIndex-1) * itemWidth
}
}