Qt 如何在QML中重新创建Android的Pull to Refresh图标?
这是Android中用于刷新视图的拉刷新图标 我一直试图把它带到qml,但这并不容易。 有如此多的转换,它很快变得非常复杂 在QML中重新创建此项应该有多困难? 使用画布是更好的解决方案吗 正如我第一次看到的,当箭头旋转时,滑动以与滑动不同的速度向下移动箭头。如果此箭头来自画布,它如何与外部事件(即滑动)关联?问题在于,在禁用视觉行为的情况下,Flickable和派生的ListView实际上不提供任何过度拖动或过度拍摄信息 如果在开始处拖动视图对您来说不是问题,那么您可以简单地使用contentY的否定值,如果在视图开始之前拖动视图,则该值将变为否定值 我能想到的唯一解决方案是,不进行任何视觉过度拖动,但仍然获得过度拖动信息,以便驱动刷新程序,就是将view interactive属性设置为false,并在其上放置另一个鼠标区域,然后手动将拖动和轻弹重定向到现在的非交互视图 最后一部分听起来可能很复杂,但它并没有那么复杂,我碰巧知道它工作得很好,因为我已经使用了这种方法 因此,一旦您访问了控制视图的鼠标区域,您就可以跟踪负片的数量,并使用该信息驱动刷新器的逻辑和动画 链接答案中的实现与您需要的实现之间的显著区别在于,由于我想要解决的特定问题的要求,链接答案在每个代理中都有鼠标区域。您不需要这样做,您只需要一个覆盖视图的鼠标区域。问题是,在禁用视觉行为的情况下,Flickable和派生的ListView实际上不提供任何过度拖动或过度拍摄信息 如果在开始处拖动视图对您来说不是问题,那么您可以简单地使用contentY的否定值,如果在视图开始之前拖动视图,则该值将变为否定值 我能想到的唯一解决方案是,不进行任何视觉过度拖动,但仍然获得过度拖动信息,以便驱动刷新程序,就是将view interactive属性设置为false,并在其上放置另一个鼠标区域,然后手动将拖动和轻弹重定向到现在的非交互视图 最后一部分听起来可能很复杂,但它并没有那么复杂,我碰巧知道它工作得很好,因为我已经使用了这种方法 因此,一旦您访问了控制视图的鼠标区域,您就可以跟踪负片的数量,并使用该信息驱动刷新器的逻辑和动画Qt 如何在QML中重新创建Android的Pull to Refresh图标?,qt,qml,Qt,Qml,这是Android中用于刷新视图的拉刷新图标 我一直试图把它带到qml,但这并不容易。 有如此多的转换,它很快变得非常复杂 在QML中重新创建此项应该有多困难? 使用画布是更好的解决方案吗 正如我第一次看到的,当箭头旋转时,滑动以与滑动不同的速度向下移动箭头。如果此箭头来自画布,它如何与外部事件(即滑动)关联?问题在于,在禁用视觉行为的情况下,Flickable和派生的ListView实际上不提供任何过度拖动或过度拍摄信息 如果在开始处拖动视图对您来说不是问题,那么您可以简单地使用content
链接答案中的实现与您需要的实现之间的显著区别在于,由于我想要解决的特定问题的要求,链接答案在每个代理中都有鼠标区域。你不需要这样做,你只需要一个覆盖视图的鼠标区域。我找到了一个更简单的解决方案,它涉及多个Flickable元素,基本上包括用鼠标earea填充Flickable,将其boundsBehavior属性设置为Flickable.StopAtBounds,如果它位于顶部,基于鼠标值做事情 我可以在下面的代码中得到更好的近似值。一个可能的缺点是对角滑动也算作刷新意图。它可以改进,但我太懒了,现在还没弄到手
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Window 2.2
ApplicationWindow {
property real mm: Screen.pixelDensity
property real margins: 2 * mm
id: mainWindow
visible: true
width: 60 * mm
height: 120 * mm
title: qsTr("Hello World")
ListModel {
id: myModel
Component.onCompleted: {
for(var i = 0; i <= 100; ++i) {
myModel.append({num: i})
}
}
}
ListView {
id: view
boundsBehavior: Flickable.StopAtBounds
interactive: true
anchors.fill: parent
model: myModel
spacing: 4
delegate: Rectangle {
width: parent.width
height: 25 * mm
border.color: 'red'
Text {
id: name
text: num
anchors.centerIn: parent
}
}
Rectangle {
signal follow
id: swatch
width: 15 * mm
height: width
radius: width / 2
color: 'lightgray'
anchors.horizontalCenter: parent.horizontalCenter
y: - height
}
MouseArea {
property int mouseYSart
property int biggerMouseY
anchors.fill: view
onPressed: {
mouseYSart = mouseY
biggerMouseY = 0
}
onMouseYChanged: {
if(view.contentY == 0) {
var currentMouseY = mouseY
if(currentMouseY > biggerMouseY) {
biggerMouseY = currentMouseY
swatch.y += 1
}
if(currentMouseY < biggerMouseY) {
biggerMouseY = currentMouseY
swatch.y -= 1
}
}
}
onReleased: swatch.y = - swatch.height
}
}
}
我找到了一个更简单的解决方案,它涉及到多个Flickable元素,基本上包括用MouseArea填充Flickable,将其boundsBehavior属性设置为Flickable.StopAtBounds,然后,如果它位于顶部,则根据mouseY值进行操作 我可以在下面的代码中得到更好的近似值。一个可能的缺点是对角滑动也算作刷新意图。它可以改进,但我太懒了,现在还没弄到手
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Window 2.2
ApplicationWindow {
property real mm: Screen.pixelDensity
property real margins: 2 * mm
id: mainWindow
visible: true
width: 60 * mm
height: 120 * mm
title: qsTr("Hello World")
ListModel {
id: myModel
Component.onCompleted: {
for(var i = 0; i <= 100; ++i) {
myModel.append({num: i})
}
}
}
ListView {
id: view
boundsBehavior: Flickable.StopAtBounds
interactive: true
anchors.fill: parent
model: myModel
spacing: 4
delegate: Rectangle {
width: parent.width
height: 25 * mm
border.color: 'red'
Text {
id: name
text: num
anchors.centerIn: parent
}
}
Rectangle {
signal follow
id: swatch
width: 15 * mm
height: width
radius: width / 2
color: 'lightgray'
anchors.horizontalCenter: parent.horizontalCenter
y: - height
}
MouseArea {
property int mouseYSart
property int biggerMouseY
anchors.fill: view
onPressed: {
mouseYSart = mouseY
biggerMouseY = 0
}
onMouseYChanged: {
if(view.contentY == 0) {
var currentMouseY = mouseY
if(currentMouseY > biggerMouseY) {
biggerMouseY = currentMouseY
swatch.y += 1
}
if(currentMouseY < biggerMouseY) {
biggerMouseY = currentMouseY
swatch.y -= 1
}
}
}
onReleased: swatch.y = - swatch.height
}
}
}
我用了这样的方法:
//
// Slot called when the flick has started
//
onFlickStarted: {
refreshFlik = atYBeginning
}
//
// Slot called when the flick has finished
//
onFlickEnded: {
if ( atYBeginning && refreshFlik )
{
refresh()
}
}
它似乎如预期的那样工作,并且很容易实现我使用了类似这样的方法:
//
// Slot called when the flick has started
//
onFlickStarted: {
refreshFlik = atYBeginning
}
//
// Slot called when the flick has finished
//
onFlickEnded: {
if ( atYBeginning && refreshFlik )
{
refresh()
}
}
它看起来像预期的那样工作,而且很容易实现这实际上相当容易实现。如果您在设想实现方面有困难,我想说,在开始使用它之前,您还有一些需要学习的地方。我不是要代码,我甚至不喜欢它。只是需要一些关于实现的一般性解释。。。一些方向。我现在是个新手,你知道当你不知道做smth需要什么工具时,学习起来很难。这里有经验的开发人员给出的答案帮助很大。
顺便说一句,谢谢你的建议。只需使用z定位和锚定将图像放置在列表或任何东西上。将MouseArea放入其中以获取onClick事件并刷新列表。OP询问的是这样一个动画:,虽然它在QML中是可行的,但它肯定不是微不足道的。检查是一个很好的起点。至于箭头的渲染,无论是画布还是Qt5.10中的新形状模块看起来都不错。谢谢@GrecKo。不幸的是,我的Qt版本是5.7,但Flickable.verticalOverShoot是在v中引入的。5.9. 我真的在考虑升级。到目前为止,尽管将boundsBehavior设置为stopAtBounds,但我无法检查ListView的隐式垂直位置,因为它总是在顶部有边界。知足也变得毫无用处。这实际上相当容易实现。如果您在设想实现方面有困难,我想说,在开始使用它之前,您还有一些需要学习的地方。我不是要代码,我甚至不喜欢它。只是需要一些关于实现的一般性解释。。。一些方向。我现在是个新手,你知道当你不知道做smth需要什么工具时,学习起来很难。这里有经验的开发人员给出的答案帮助很大。顺便说一句,谢谢你的建议。只需使用z定位和锚定将图像放置在列表或任何东西上。将MouseArea放入其中以获取onClick事件并刷新列表。OP询问的是这样一个动画:,虽然它在QML中是可行的,但它肯定不是微不足道的。检查是一个很好的起点。至于箭头的渲染,无论是画布还是Qt5.10中的新形状模块看起来都不错。谢谢@GrecKo。不幸的是,我的Qt版本是5.7,但Flickable.verticalOverShoot是在v中引入的。5.9. 我真的在考虑升级。到目前为止,尽管将boundsBehavior设置为stopAtBounds,但我无法检查ListView的隐式垂直位置,因为它总是在顶部有边界。contentY也变得毫无用处。不过它确实有超调:即使boundsMovement是可Flickable,也会报告超调距离。StopAtBounds.OK,与文档所述相反,StopAtBounds不会报告超调。至少在我使用的5.9.1中没有。当超调球出现时会报告,但仅用于轻弹,不用于拖动,对于DragOverBounds会报告,但不用于轻弹,内容不会停留在边界上,当然,对于DragAndOvershootBounds会报告,但StopAtBounds是需要的,超调值不会随它而变化,它始终为0。看起来它与boundsMovement有关,boundsMovement是5.10版本的东西。事实上,它是在5.10版本中添加的,对于任何使用5.10+的人来说,它将提供一种简单的方法来获得90%的期望行为。对我来说,这不是一个选择,因为回归。当然,如果没有对用户交互的明确控制,就不可能获得准确的行为。不过,它确实有过冲:即使boundsMovement是Flickable,也会报告过冲距离。StopAtBounds.OK,与文档所述相反,StopAtBounds不会报告过冲。至少在我使用的5.9.1中没有。当超调球出现时会报告,但仅用于轻弹,不用于拖动,对于DragOverBounds会报告,但不用于轻弹,内容不会停留在边界上,当然,对于DragAndOvershootBounds会报告,但StopAtBounds是需要的,超调值不会随它而变化,它始终为0。看起来它与boundsMovement有关,boundsMovement是5.10版本的东西。事实上,它是在5.10版本中添加的,对于任何使用5.10+的人来说,它将提供一种简单的方法来获得90%的期望行为。对我来说,这不是一个选择,因为回归。当然,如果没有对用户交互的明确控制,就不可能获得准确的行为。