(垂直)滚动视图包含另一个(水平)滚动视图 - Kivy

Posted

技术标签:

【中文标题】(垂直)滚动视图包含另一个(水平)滚动视图 - Kivy【英文标题】:(Vertical) ScrollView containing another (horizontal) scrollview - Kivy 【发布时间】:2019-08-03 15:37:00 【问题描述】:

我的目标是有一个网格布局(垂直),其中包含另一个仅水平滚动的滚动视图,但第二个滚动视图在触摸时不滚动,仅在触摸时移动。

最好使用 RecycleView 吗?如果是这样,我该如何实施?谢谢!

代码示例:

ScrollView:
    bar_width: 5
    scroll_type: ['bars', 'content']
    do_scroll: (False, True)
    size_hint_y: None
    height: Window.height
    GridLayout:
        id: main_box
        size_hint_y: None
        cols: 1
        height: self.minimum_height
        Button:
            size_hint_y: None
            height: 50
        ScrollView:
            bar_width: 5
            scroll_type: ['bars', 'content']
            do_scroll: (True, False)
            size_hint_y: None
            effect_cls: "ScrollEffect"
            height: Window.height/4.5
            GridLayout:
                id: horizontal_grid
                rows: 1
                padding: [10, 10]
                size: self.minimum_size
                size_hint: None, None
        Button:
            size_hint_y: None
            height: 50

【问题讨论】:

【参考方案1】:

这是一个非常丑陋的 hack,它可以满足我的需求。 MyScrollView 类覆盖 on_touch_down 方法,如果触摸在内部 ScrollView 内,则将该触摸发送到内部 ScrollView

from kivy.app import App
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.label import Label
from kivy.uix.scrollview import ScrollView


class MyScrollView(ScrollView):
    def on_touch_down(self, touch):
        # get touch position in coordinates of the main_box (parent of inner_scroll)
        x,y = self.ids.main_box.to_widget(*self.to_window(*touch.pos))

        # if converted position is within the inner_scroll, send touch to the inner_scroll
        if self.ids.inner_scroll.collide_point(x,y):
            touch.pos = (x,y)   # change touch position to coordinates in main_box
            return self.ids.inner_scroll.on_touch_down(touch)   # call on_touch of inner_scroll
        else:
            return super(MyScrollView, self).on_touch_down(touch)

theRoot = Builder.load_string('''
#: import Window kivy.core.window.Window
MyScrollView:
    bar_width: 5
    scroll_type:['bars', 'content']
    do_scroll: (False, True)
    size_hint_y: None
    height: Window.height
    GridLayout:
        id: main_box
        size_hint_y: None
        cols: 1
        height: self.minimum_height
        Button:
            size_hint_y: None
            height: 50
        ScrollView:
            id: inner_scroll
            bar_width: 5
            scroll_type: ['bars', 'content']
            do_scroll: (True, False)
            size_hint_y: None
            effect_cls: "ScrollEffect"
            height: Window.height/4.5
            GridLayout:
                id: horizontal_grid
                rows: 1
                padding: [10, 10]
                size: self.minimum_size
                size_hint: None, None
        Button:
            size_hint_y: None
            height: 50
''')



class ScrollTwoApp(App):
    def build(self):
        Clock.schedule_once(self.add_members)
        return theRoot

    def add_members(self, dt):
        for i in range(25):
            theRoot.ids.main_box.add_widget(Label(text='label'+str(i), size_hint=(1.0, None), height=25))
            theRoot.ids.horizontal_grid.add_widget(Label(text='Hlabel' + str(i), size_hint=(None, 1), width=75))


ScrollTwoApp().run()

需要添加inner_scroll id,并将外部ScrollView 更改为MyScrollView

【讨论】:

谢谢你!!!这太棒了我试图做这样的事情但做不到,我真的很感谢你的帮助!你真棒

以上是关于(垂直)滚动视图包含另一个(水平)滚动视图 - Kivy的主要内容,如果未能解决你的问题,请参考以下文章

水平滚动视图不滚动

水平 UIScrollView 内部有垂直 UIScrollViews - 滚动外部水平视图时如何防止滚动内部滚动视图?

android中的垂直和水平滚动视图

android中的垂直和水平滚动视图

滚动其他滚动视图时滚动视图重置

在拆分视图中同步垂直/水平滚动