Search code examples
pythonkivyrecyclerview-layout

How to use RecycleView in kivy?


Based on the code that is posted on kivy docs about Recycle View, how do I change the data? how to change the size of the selectable labels? and especially if I want to have more widget on the screen, how do set the position of the list to be in the bottom side of the screen?

I've tried to change the position with GridLayout, BoxLayout and nothing happens.

'''
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

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:
        default_size: None, dp(56)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'
        multiselect: True
        touch_multiselect: 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
        if is_selected:
            print("selection changed to {0}".format(rv.data[index]))
        else:
            print("selection removed for {0}".format(rv.data[index]))

class RV(RecycleView):
    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        self.data = [{'text': str(x)} for x in range(100)]


class TestApp(App):
    def build(self):
        return RV()

if __name__ == '__main__':
     TestApp().run()

'''


Solution

  • Question 1

    How do I change the data?

    Answer

    Change the data by updating self.data

    RecycleView » data

    The RecycleView is generatad by processing the data (i.e. self.data), essentially a list of dicts, and uses these dicts to generate instances of the viewclass as required.

    Question 2

    How to change the size of the selectable labels?

    Answer

    The size especially the height of each selectable widgets can be change in either Python script or kv file.

    With reference to this example, the height can be changed by setting default_size: None, dp(30) at SelectableRecycleBoxLayout. As for the width of each selectable widgets, it will change according to the number columns in a row of data, self.data

    With a SelectableRecycleGridLayout, one can specify the minimum width for each column by using cols_minimum

    Question 3

    If I want to have more widget on the screen, how to set the position of the list to be in the bottom side of the screen?

    Answer

    • Declare a root widget with inheritance of BoxLayout

    Snippets

    <RootWidget>:
        orientation: 'vertical'
        BoxLayout:
            size_hint: 1, 0.8
        BoxLayout:
            size_hint: 1, 0.2
            RV:
    

    Output

    RecyclView of Buttons

    Example

    How to add vertical scroll in RecycleView