从Kivy Recycleview

时间:2017-10-14 01:21:11

标签: python listview android-recyclerview kivy

我已经在以前版本的Kivy中编写了一些使用ListViews的程序。使用ListViews,通过适配器获取所选节点非常容易。但是,如何使用RecycleView进行此操作还不太清楚。现在,可以使用rv.layout_manager.selected_nodes来获取所选值,但也有时候我对实际节点感兴趣。此外,以下代码段可用于生成节点,但显然,它们不是RecycleView中的实际节点。

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

我有兴趣找到一种从RecycleView获取所选节点的方法。

完整代码:

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('''
<SelectableLabel>:
    # 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
<RV>:
    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()

1 个答案:

答案 0 :(得分:1)

请告诉我们您的代码。在rv.data中,您可以添加一个参数&#39; selected&#39;未选择节点时为0,如果是,则为1:

class TestRecycleView(RecycleView):

   def __init__(self, **kwargs):
      super(TestRecycleView, self).__init__(**kwargs)
      self.data = [{'name': 'test', 'ind':0,'selected': 0}]

class TestBox(RecycleDataBehaviour, BoxLayout):
   def action(self, boss):
      if boss.data[self.ind]['selected'] == 0:
         boss.data[self.ind]['selected'] = 1
      else:
         boss.data[self.ind]['selected'] = 0

kv:

<TestRecycleView>:
   viewclass: 'TestBox'
   RecycleBoxLayout:
      default_size: None, 440
      default_size_hint: 1, None
      size_hint_y: None
      height: self.minimum_height
      orientation: 'vertical'
<TestBox>:
   Button:
      on_press: root.action(root.parent.parent)

如果我理解你想要打印selectedLabel值:

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 self.rv.data[val[0]]['text']

proof(image link)