title: Get selected node from Kivy Recycleview
body: <p>I've got some programs written in previous versions of Kivy that use ListViews. Using ListViews, it was quite easy to get the selected node via the adapter. However, it is much less clear how to do this with a RecycleView. Now, it is the case that <code>rv.layout_manager.selected_nodes</code> can be used to get the selected value, but there are also times where I'm interested in the actual node. Also, the following snippet can be used to generate the nodes, but apparently, they aren't the actual nodes in the RecycleView.</p>
  
  <pre><code>opts = rv.layout_manager.view_opts
  for i in range(len(rv.data)):
      s = rv.view_adapter.get_view(i, rv.data[i], opts[i]['viewclass'])
      print s.text, s.selected
  </code></pre>
  
  <p>I'd be interested in finding a way of getting the selected node from the RecycleView.</p>
  
  <p>Full code:</p>
  
  <pre><code>import random
  from kivy.app import App
  from kivy.lang import Builder
  from kivy.uix.recycleview import RecycleView
  from kivy.uix.recycleview.views import RecycleDataViewBehavior
  from kivy.uix.label import Label
  from kivy.properties import BooleanProperty
  from kivy.uix.recycleboxlayout import RecycleBoxLayout
  from kivy.uix.behaviors import FocusBehavior
  from kivy.uix.recycleview.layout import LayoutSelectionBehavior
  
  #Aside: the code in the string would need to be indented back one tab, but it's like this for SO formatting
  Builder.load_string('''
  &lt;SelectableLabel&gt;:
      # Draw a background to indicate selection
      canvas.before:
          Color:
          rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
          Rectangle:
              pos: self.pos
              size: self.size
  &lt;RV&gt;:
      viewclass: 'SelectableLabel'
      SelectableRecycleBoxLayout:
          key_selection: "True"
          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
          touch_deselect_last: True
  ''')
  
  
  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
  
  
  class RV(RecycleView):
      def __init__(self, **kwargs):
          super(RV, self).__init__(**kwargs)
          self.data = [{'text': str(random.random())} for x in range(20)]
  
  
  class TestApp(App):
      def build(self):
          self.rv = RV()
          self.rv.layout_manager.bind(selected_nodes=self.selectionChange)
          return self.rv
  
      def selectionChange(self, inst, val):
          print inst, val
  
  if __name__ == '__main__':
      b = TestApp()
      b.run()
  </code></pre>