QML实现Android计时器选择器数字随手柄遮罩变色效果
可以用QML实现该交互效果,具体实现方案如下:
核心思路是实时检测手柄与数字文本的矩形碰撞,根据碰撞结果切换数字颜色,同时实现手柄的拖动交互。
实现步骤与代码示例
1. 基础布局搭建
创建包含数字列表和可拖动手柄的容器,用深色背景突出文字颜色变化:
import QtQuick 2.15 import QtQuick.Window 2.15 Window { width: 200 height: 400 visible: true title: "Timer Picker" // 深色背景 Rectangle { anchors.fill: parent color: "#333" } // 垂直排列的数字列表 Column { id: numberColumn anchors.centerIn: parent spacing: 20 // 生成0-9的数字文本 Repeater { model: 10 Text { id: numberText text: index font.pixelSize: 32 // 初始浅灰,重叠时切换为白色 color: isOverlapped ? "white" : "#ccc" // 标记是否与手柄重叠 property bool isOverlapped: false } } } // 可拖动的半透明手柄 Rectangle { id: handle width: 80 height: 60 color: "rgba(255,255,255,0.3)" radius: 8 anchors.horizontalCenter: parent.horizontalCenter y: 150 MouseArea { anchors.fill: parent drag.target: handle drag.axis: Drag.YAxis drag.minimumY: 0 drag.maximumY: parent.height - handle.height } } }
2. 碰撞检测与颜色切换
通过监听手柄的位置变化,实时判断每个数字文本与手柄的矩形是否相交(包含部分重叠的情况),并更新数字的颜色状态:
将上述代码中Repeater内的Text组件替换为以下代码:
Text { id: numberText text: index font.pixelSize: 32 color: isOverlapped ? "white" : "#ccc" property bool isOverlapped: false // 监听手柄位置变化,更新重叠状态 Connections { target: handle onYChanged: { // 转换为全局坐标,确保碰撞判断不受父容器位置影响 const textGlobalRect = Qt.rect( numberText.mapToGlobal(0, 0).x, numberText.mapToGlobal(0, 0).y, numberText.width, numberText.height ); const handleGlobalRect = Qt.rect( handle.mapToGlobal(0, 0).x, handle.mapToGlobal(0, 0).y, handle.width, handle.height ); // 判断两个矩形是否相交 numberText.isOverlapped = Qt.rectIntersects(textGlobalRect, handleGlobalRect); } } }
3. 扩展与优化
- 若需水平方向的选择器,只需将
Column改为Row,并把手柄拖动轴改为Drag.XAxis,限制拖动范围为水平方向即可。 - 上述代码仅在手柄移动时更新碰撞状态,避免了每帧计算的性能损耗,数字数量较多时更高效。
内容的提问来源于stack exchange,提问作者FalsinSoft
相关产品推荐
相关产品推荐

