Kivy ScrollView与ScreenManager:如何处理过滚动值并在主屏幕触发事件
解决方案:让Effect类获取StartScreen的引用
你的核心问题在于自定义的Effect类无法访问到StartScreen实例,所以没法调用它的prev_key和next_key方法。我们可以通过给Effect添加一个属性来存储StartScreen的引用,然后在合适的时机把引用传过去,具体步骤如下:
1. 修改Effect类,添加screen属性
在Effect的初始化方法里新增一个screen属性,用来保存StartScreen的实例:
class Effect(DampedScrollEffect): def __init__(self, *args, **kwargs): super(Effect, self).__init__(**kwargs) self.screen = None # 新增:用来存储StartScreen实例 def on_overscroll(self, *args): self.args = args if self.overscroll < -100: self.scrollup() elif self.overscroll > 100: self.scrolldown() @CallControl(max_call_interval=1) def scrollup(self): if self.screen: # 确保screen引用存在再调用方法 self.screen.prev_key() @CallControl(max_call_interval=1) def scrolldown(self): if self.screen: # 确保screen引用存在再调用方法 self.screen.next_key()
2. 在StartScreen中传递引用给Effect
修改StartScreen的finish_init方法,把当前StartScreen实例赋值给ScrollView的effect的screen属性:
def finish_init(self, dt): self.update_container() # 新增:把当前StartScreen实例传给Effect self.ids.scroller.effect.screen = self
3. 修复prev_key方法的逻辑bug
你的prev_key方法里的判断条件有误,len(self.keys)是列表的长度,对应的索引并不存在(索引从0开始),应该改为判断是否是第一个索引:
def prev_key(self, *args): idx = self.keys.index(self.num) if idx == 0: print('no more keys in the dict...') else: self.num = self.keys[idx - 1] self.update_container()
为什么这样可行?
ScrollView的effect属性就是我们自定义的Effect实例,在StartScreen初始化完成后,我们可以通过self.ids.scroller.effect获取到它,然后把当前StartScreen实例赋值给它的screen属性。- 这样当
Effect触发scrollup或scrolldown时,就可以通过self.screen调用StartScreen的方法,实现数据切换。
测试一下,现在当你在ScrollView里滚动到底部触发overscroll大于100时,就会调用next_key;滚动到顶部触发overscroll小于-100时调用prev_key,容器里的内容就会跟着切换了。
内容的提问来源于stack exchange,提问作者speckles
相关产品推荐
相关产品推荐

