2017-10-06 136 views
0

我有一個RecycleView小部件,用於響應觸摸輸入。我需要RecycleView上的每一行將用戶帶到特定的屏幕。目前我只有兩個屏幕設置。在Kivy中使用ScreenManager和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() 

如果你看一下apply_selection方法,這是在SelectableLabel類,你會看到,我已嘗試通過檢查來排序了這一點:

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

有兩種方法可以做到這一點,從我的頭頂。 一種是使用路由器模塊中的kivy花園:

https://github.com/kivy-garden/garden.router

另一種是通過在循環視圖通過屏幕管理的參考部件,這樣你就可以說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) 

這樣,您就可以通過編程創建的每個畫面,將它們定義爲單獨的類。