使用 RecycleView 滚动时如何保持我的 Kivy ToggleButton 状态?
How can I keep my Kivy ToggleButton state when scrolling using a RecycleView?
如果我创建一个 ToggleButton 列表并将它们放在 RecycleView 中,切换一个 ToggleButton 会导致视图外的 ToggleButton 通过滚动进出视图来更改状态。我是否错误地实施了 RecycleView?
如果我使用按钮而不是切换按钮,我的 RecycleView 会按预期工作。
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.properties import StringProperty,NumericProperty
Builder.load_string("""
<MyLayout>:
orientation: 'vertical'
spacing: 10
RV:
<RV>:
viewclass: 'RecycleViewRow'
RecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
<RecycleViewRow>:
orientation: 'horizontal'
ToggleButton:
text: root.text
""")
class MyLayout(BoxLayout):
pass
class RecycleViewRow(BoxLayout):
text = StringProperty()
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.data = [{'text': "Button " + str(x+1)} for x in range(30)]
class MainscreenApp(App):
def build(self):
return MyLayout()
if __name__=="__main__":
MainscreenApp().run()
这里是对执行 self.data
更新的代码的修改:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.properties import StringProperty
Builder.load_string("""
<MyLayout>:
orientation: 'vertical'
spacing: 10
RV:
id: rv
<RV>:
viewclass: 'RecycleViewRow'
RecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
<RecycleViewRow>:
orientation: 'horizontal'
ToggleButton:
id: tb
text: root.text
state: root.state
on_release: app.root.ids.rv.adjust_data(root)
""")
class MyLayout(BoxLayout):
pass
class RecycleViewRow(BoxLayout):
text = StringProperty()
state = StringProperty('normal')
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.data = [{'text': "Button " + str(x+1), 'state': "normal"} for x in range(30)]
def adjust_data(self, rvRow):
for d in self.data:
if d['text'] == rvRow.text:
d['state'] = rvRow.ids.tb.state
rvRow.state = rvRow.ids.tb.state
break
class MainscreenApp(App):
def build(self):
return MyLayout()
if __name__=="__main__":
MainscreenApp().run()
如果我创建一个 ToggleButton 列表并将它们放在 RecycleView 中,切换一个 ToggleButton 会导致视图外的 ToggleButton 通过滚动进出视图来更改状态。我是否错误地实施了 RecycleView?
如果我使用按钮而不是切换按钮,我的 RecycleView 会按预期工作。
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.properties import StringProperty,NumericProperty
Builder.load_string("""
<MyLayout>:
orientation: 'vertical'
spacing: 10
RV:
<RV>:
viewclass: 'RecycleViewRow'
RecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
<RecycleViewRow>:
orientation: 'horizontal'
ToggleButton:
text: root.text
""")
class MyLayout(BoxLayout):
pass
class RecycleViewRow(BoxLayout):
text = StringProperty()
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.data = [{'text': "Button " + str(x+1)} for x in range(30)]
class MainscreenApp(App):
def build(self):
return MyLayout()
if __name__=="__main__":
MainscreenApp().run()
这里是对执行 self.data
更新的代码的修改:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.recycleview import RecycleView
from kivy.properties import StringProperty
Builder.load_string("""
<MyLayout>:
orientation: 'vertical'
spacing: 10
RV:
id: rv
<RV>:
viewclass: 'RecycleViewRow'
RecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
<RecycleViewRow>:
orientation: 'horizontal'
ToggleButton:
id: tb
text: root.text
state: root.state
on_release: app.root.ids.rv.adjust_data(root)
""")
class MyLayout(BoxLayout):
pass
class RecycleViewRow(BoxLayout):
text = StringProperty()
state = StringProperty('normal')
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
self.data = [{'text': "Button " + str(x+1), 'state': "normal"} for x in range(30)]
def adjust_data(self, rvRow):
for d in self.data:
if d['text'] == rvRow.text:
d['state'] = rvRow.ids.tb.state
rvRow.state = rvRow.ids.tb.state
break
class MainscreenApp(App):
def build(self):
return MyLayout()
if __name__=="__main__":
MainscreenApp().run()