You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mac触控板下Kivy ScrollView实现平滑滚动的方法

解决MacBook触控板上Kivy ScrollView平滑滚动问题

核心原因&解决思路

Kivy默认的ScrollView对Mac触控板的滚动事件未做惯性逻辑处理,手指离开后滚动会立刻停止。我们可以自定义ScrollView类,监听滚动时的速度参数,在手指离开后通过持续减速动画模拟苹果式的平滑滚动效果。

实现代码

from kivy.uix.scrollview import ScrollView
from kivy.clock import Clock
from kivy.properties import NumericProperty

class SmoothScrollView(ScrollView):
    # 减速系数:值越小减速越快,值越接近1滚动惯性越强
    deceleration = NumericProperty(0.92)
    # 停止阈值:滚动速度低于该值时终止惯性动画
    min_speed = NumericProperty(0.8)
    _scroll_speed = NumericProperty(0)
    _is_animating = False

    def on_scroll_move(self, touch):
        if touch.grab_current is self:
            # 根据帧间隔计算实时滚动速度(Y轴)
            self._scroll_speed = touch.dy / Clock.frametime
        return super().on_scroll_move(touch)

    def on_touch_up(self, touch):
        if touch.grab_current is self and abs(self._scroll_speed) > self.min_speed:
            self._start_inertial_scroll()
        return super().on_touch_up(touch)

    def _start_inertial_scroll(self):
        if not self._is_animating:
            self._is_animating = True
            Clock.schedule_interval(self._update_inertial_scroll, 1/60)

    def _update_inertial_scroll(self, dt):
        # 应用减速逻辑
        self._scroll_speed *= self.deceleration
        # 更新滚动位置
        self.scroll_y += self._scroll_speed * dt
        # 限制滚动范围在0-1之间,避免超出边界
        self.scroll_y = max(0, min(1, self.scroll_y))
        # 速度低于阈值时停止动画
        if abs(self._scroll_speed) < self.min_speed:
            self._is_animating = False
            return False
        return True

使用方式

将原有布局中的ScrollView替换为自定义的SmoothScrollView即可:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label

class TestApp(App):
    def build(self):
        main_layout = BoxLayout(orientation='vertical')
        scroll_view = SmoothScrollView()
        
        # 构建长列表内容
        content_layout = BoxLayout(orientation='vertical', size_hint_y=None)
        content_layout.height = 2000
        for i in range(50):
            content_layout.add_widget(Label(text=f"列表项 {i+1}", size_hint_y=None, height=40))
        
        scroll_view.add_widget(content_layout)
        main_layout.add_widget(scroll_view)
        return main_layout

if __name__ == '__main__':
    TestApp().run()

参数调整建议

  • 若想让滚动惯性更强,可把deceleration调至0.95左右;若希望减速更快,可设为0.85
  • 降低min_speed的值(比如0.5),会让滚动更接近完全静止时才停下,进一步贴近苹果系统的体验

内容的提问来源于stack exchange,提问作者DaveL17

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 16:02:13