alas the simple answer is: it is a kivy RecycleGridLayout issue! https://github.com/kivy/kivy/issues/7255
a poor workaround to display a single row's data, is to add dummy data for another row.
the base of code in main.py is a slightly adapted version of PalimPalim's answer to this question: Kivy - python - multiple widgets in recycleview row
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import NumericProperty, ListProperty
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.behaviors import FocusBehavior
from customRecyclegridlayout import CustomRecycleGridLayout
from Examples.RecycleGridLayout_Palim.customlayout import CustomLayoutSelectionBehavior
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'
data: root.data
SelectableRecycleGridLayout:
id: recycle_grid
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'lr-tb'
multiselect: True
touch_multiselect: True
cols: root.rv_columns
''')
class SelectableRecycleGridLayout(FocusBehavior, CustomLayoutSelectionBehavior, CustomRecycleGridLayout):
''' 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):
rv_columns = NumericProperty(3) # set number of columns in RecycleView
items = ListProperty()
data = ListProperty([])
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
items_entity_0 = []
items_entity_1 = [0, "apple", "fox"]
items_entity_2 = [0, "apple", "fox", 1, "bone", "dog"]
items_entity_3 = [0, "apple", "fox", 1, "bone", "dog", 2, 'milk', "cat"]
self.data = self._get_formatted_data(self._check_itemsList(items_entity_1))
self.app_info = App.get_running_app()
def _check_itemsList(self, item_list):
i_list = item_list
if self.rv_columns == len(i_list):
print('single row detected!')
for element in range(self.rv_columns):
i_list.append('dummy')
return i_list
@staticmethod
def _get_formatted_data(item_list):
data = [{'text': str(x)} for x in item_list]
return data
class TestApp(App):
def build(self):
return RV()
if __name__ == '__main__':
TestApp().run()