QML - 画廊效果

看网上都是通过PathView来写,但是写出来的都是首位相连的效果,并不是想要的效果,而且又改不动(接触QML不长,无奈自己写),而我想要的效果是从左往右,一页显示三个,最中间的的图片放大 。

先看效果

效果图.gif

先分析效果图 ,用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
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。