我有一个响应触摸输入的RecycleView小部件。我需要RecycleView上的每一行将用户带到特定的屏幕。现在我只有两个屏幕设置。
这是Python代码:
class Navigator(NavigationDrawer):
image_source = StringProperty('images/1canaa.jpg')
title = StringProperty('Navigation')
# This is the screen that is initiated when the app runs
class MainScreen(Screen):
pass
# This is the screen that is suppose to initiate when the first row is
# touched
class MapScreen(Screen):
pass
class Manager(ScreenManager):
main_screen_obj = ObjectProperty(None)
map_screen_obj = ObjectProperty(None)
class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
RecycleBoxLayout):
''' Adds selection and focus behaviour to the view. '''
class SelectableLabel(RecycleDataViewBehavior, Label):
''' Add selection support to the Label '''
index = None
selected = BooleanProperty(False)
selectable = BooleanProperty(True)
def refresh_view_attrs(self, rv, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(SelectableLabel, self).refresh_view_attrs(
rv, index, data)
def on_touch_down(self, touch):
''' Add selection on touch down '''
if super(SelectableLabel, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos) and self.selectable:
return self.parent.select_with_touch(self.index, touch)
def apply_selection(self, rv, index, is_selected):
''' Respond to the selection of items in the view. '''
self.selected = is_selected
if is_selected:
print("selection changed to {0}".format(rv.data[index]))
if rv.data[index] == {'text': 'FIRST ROW'}:
Manager.current = 'mapScreen'
print('The evaluation was executed')
else:
print("selection removed for {0}".format(rv.data[index]))
class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
Unidades = ['FIRST ROW', 'SECOND ROW', 'THIRD ROW', 'FORTH ROW']
self.data = [{'text': x} for x in Unidades]
class Main(App):
theme_cls = ThemeManager()
nav_drawer = ObjectProperty()
def build(self):
self.nav_drawer = Navigator()
return Manager()
if __name__ == '__main__':
Main().run()
如果你看一下selectableLabel类中的apply_selection方法,你会看到我试图通过检查来解决这个问题:
if the rv.data[index] == {'text': 'FIRST ROW'}:
Manager.current = 'mapScreen'
print('The evaluation was executed')
这不起作用。请注意,我打印了一条消息,以检查评估是否已经发生,并且确实如此。当我运行应用程序时,我收到消息:“评估已执行”。但是用户没有被带到MapScreen。
这是kv代码:
#:import MapSource mapview.MapSource
#:import Toolbar kivymd.toolbar.Toolbar
#:import hex kivy.utils.get_color_from_hex
<SelectableLabel>:
# Draw a background to indicate selection
canvas.before:
Color:
rgba: hex('#867979') if self.selected else hex('#808080')
Rectangle:
pos: self.pos
size: self.size
<RV>:
viewclass: 'SelectableLabel'
SelectableRecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
multiselect: False
touch_multiselect: True
<MainScreen>:
BoxLayout:
orientation: 'vertical'
Label:
size_hint: None, None
height: 45
width: 100
pos_hint: {'center_y': 0.5, 'center_x': 0.5}
text: '[size=40]Unidades de Assistência[/size]'
color: hex('#676767')
markup: True
font_name: 'alex-brush.regular.ttf'
RV:
<MapScreen>:
BoxLayout:
Label:
text: 'MapScreen'
<Manager>:
id: screen_manager
main_screen_obj: main_screen
map_screen_obj: map_screen
MainScreen:
id: main_screen
name: 'mainScreen'
manager: screen_manager
MapScreen:
id: map_screen
name: 'mapScreen'
manager: screen_manager
所以,我在这里想要完成的事情非常简单,或者至少它应该是。这一切归结为:如果触摸了第一行,请将用户带到MapScreen ...如果触摸了第二行,请将用户带到其他屏幕......等等。
我希望这不是很混乱。谢谢你的帮助。
答案 0 :(得分:0)
有两种方法可以做到这一点,从头到尾。 一种是在kivy花园中使用路由器模块:
https://github.com/kivy-garden/garden.router
另一个是将screenmanager的引用传递给循环视图中的小部件,这样您就可以说self.manager.current = self.text
,但这意味着您必须先将所有屏幕添加到管理器中。
我会用这个工厂:
from kivy.factory import Factory
class MyScreenManager(ScreenManager):
def create_and_switch_screen(self, name):
# This creates an instance of the class name you passed
new_screen = getattr(Factory, name)()
self.switch_to(my_screen)
通过这种方式,您可以以编程方式创建每个屏幕并将它们定义为单独的类。