前提
近期在使用QML实现一个 PDF阅读器预览的窗口的功能,但是需求原因我不能直接使用ListView的自带的滚动的效果,所以这里得我自己来根据contentY来设置PDF预览的位置。
具体的做法是 我这里使用了一个MultiPointTouchArea 来识别当前是否为多指(俩个手指头),然后计算俩个手指的坐标信息,当手指移动,计算移动距离,然后直接给ListView 的 contentY的属性增加相应的值。例如 listview.contentY += moveLength
但是一旦ListView的委托的Item宽度或者高度修改之后,就会引起各种问题。
例如:
- PDF滚动限制到第一页不能继续往上滚动失效
- PDF滚动限制到最后不能继续往下滚动
实际情况可能是当我双指滚动PDF文件浏览的时候,到最后一页某个位置的时候便不能继续移动。
还有一种情况是这样,PDF默认初始化出来,我将它滚动移动到某个位置,然后开始放大我的窗口到某个位置,然后开始缩小到某个位置。这个过程,通过监听ListView height变化 打印 contentY的值发现其始终不变(和开始移动到位置的那个contentY一致)
具体解决方案
通过查看文档
可以看到文档中有提到
ListView和GridView可能有一个任意的起源,由于委托大小的变化,或项目插入/删除在外可见区域。
所以当我们需要通过contentY来达到预览ListView的需求的时候而且委托的大小可能变化的时候,我们就必须结合contentY 和 originY的实现自己的需求。
暂时不清楚为什么这里不设计为contentY就是代表内容的具体位置,还要结合originY.
所以因为惯性常规理解,我们通常将originY 理解为永远为0 那么 在开发中就需要注意一下。
为了方便理解在实际开发过程中我总结出来几条经验。
- 当需要设置contentY 的时候最好在contentY右边的表达式加上 originY 例如:
contentY = otherValue + originY - 当需要使用contentY的时候 最好给其减去originY
contentY - originY
此时就能满足我的需求了,在可以正常自定义位置调节的同时即使委托的值发生变化也可以正常使用。