Started writing formal examples for ListView in its doc header, which prompted several clean-ups. ListItemButton and ListItemLabel were added to listview.py, so that various custom ListItem classes made for the examples and tests could be removed. The todo list for this uix-listview branch was moved to a gist. A new adapters/util.py file was added, containing only list_item_args_adapter(). ListAdapter was modified to check for an args_converter argument, and if not present, to use the default one in adapters/util.py.

This commit is contained in:
Jeff Pittman 2012-07-30 22:39:15 -05:00
parent f292049d4c
commit b530e42850
10 changed files with 205 additions and 267 deletions

View File

@ -3,7 +3,7 @@ from kivy.adapters.listadapter import ListAdapter, \
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.listview import ListView
from kivy.uix.listview import ListView, ListItemButton
from kivy.adapters.mixins.selection import SingleSelectionObserver, \
SelectableItem
from kivy.properties import ListProperty, StringProperty, ObjectProperty
@ -18,27 +18,6 @@ from kivy.properties import ListProperty, StringProperty, ObjectProperty
# Generic list item will do fine for both list views:
class ListItem(SelectableItem, Button):
selected_color = ListProperty([1., 0., 0., 1])
deselected_color = None
def __init__(self, **kwargs):
super(ListItem, self).__init__(**kwargs)
# Set deselected_color to be default Button bg color.
self.deselected_color = self.background_color
def select(self, *args):
print self.text, 'is now selected'
self.background_color = self.selected_color
def deselect(self, *args):
print self.text, 'is now unselected'
self.background_color = self.deselected_color
def __repr__(self):
return self.text
class DetailView(SingleSelectionObserver, GridLayout):
fruit_name = StringProperty('')
@ -97,7 +76,7 @@ class CascadingView(GridLayout):
args_converter=list_item_args_converter,
selection_mode='single',
allow_empty_selection=False,
cls=ListItem)
cls=ListItemButton)
fruit_categories_list_view = \
ListView(adapter=fruit_categories_list_adapter,
size_hint=(.2, 1.0))
@ -113,7 +92,7 @@ class CascadingView(GridLayout):
args_converter=list_item_args_converter,
selection_mode='single',
allow_empty_selection=False,
cls=ListItem)
cls=ListItemButton)
fruits_list_view = \
ListView(adapter=fruits_list_adapter,
size_hint=(.2, 1.0))

View File

@ -5,7 +5,7 @@ from kivy.uix.button import Button
from kivy.properties import ObjectProperty, \
NumericProperty, ListProperty, \
StringProperty
from kivy.uix.listview import ListView
from kivy.uix.listview import ListView, ListItemButton
from kivy.adapters.mixins.selection import SelectionObserver, SelectableItem
from kivy.adapters.listadapter import ListAdapter
@ -33,60 +33,17 @@ from kivy.adapters.listadapter import ListAdapter
# For the master list, we need to create a custom "list item" type that
# subclasses SelectableItem.
# "Sub" to indicate that this class is for "sub" list items -- a list item
# could consist of a button on the left, several labels in the middle, and
# another button on the right. Not sure of the merit of allowing, perhaps,
# some "sub" list items to react to touches and others not, if that were to
# be enabled.
class ListItemSubButton(SelectableItem, Button):
selected_color = ListProperty([1., 0., 0., 1])
deselected_color = None
def __init__(self, **kwargs):
super(ListItemSubButton, self).__init__(**kwargs)
# Set deselected_color to be default Button bg color.
self.deselected_color = self.background_color
# [TODO] At least there is some action on this set, but
# the color gets somehow composited.
def select(self, *args):
self.background_color = self.selected_color
# [TODO] No effect seen, but it is grey, so might be happening.
def deselect(self, *args):
self.background_color = self.deselected_color
def __repr__(self):
return self.text
# A composite list item could consist of a button on the left, several labels
# in the middle, and another button on the right. Not sure of the merit of
# allowing, perhaps, some "sub" list items to react to touches and others not,
# if that were to be enabled.
class ListItemSubLabel(SelectableItem, Label):
# Same idea as "sub" for button above.
selected_color = ListProperty([1., 0., 0., 1])
deselected_color = ListProperty([.33, .33, .33, 1])
def __init__(self, **kwargs):
super(ListItemSubLabel, self).__init__(**kwargs)
# [TODO] Should Label have background_color, like Button, etc.?
# [TODO] Not tested yet.
def select(self, *args):
self.bold = True
def deselect(self, *args):
self.bold = False
def __repr__(self):
return self.text
class ListItem(SelectableItem, BoxLayout):
# ListItem (BoxLayout) by default uses orientation='horizontal',
class CompositeListItem(SelectableItem, BoxLayout):
# CompositeListItem (BoxLayout) by default uses orientation='horizontal',
# but could be used also for a side-to-side display of items.
#
# ListItemSubButton sublasses Button, which has background_color.
# ListItemButton sublasses Button, which has background_color.
# Here we must add this property.
background_color = ListProperty([1, 1, 1, 1])
@ -97,11 +54,11 @@ class ListItem(SelectableItem, BoxLayout):
content_button = ObjectProperty(None)
def __init__(self, **kwargs):
super(ListItem, self).__init__(**kwargs)
super(CompositeListItem, self).__init__(**kwargs)
# Now this button just has text '>', but it would be neat to make the
# left button hold icons -- the list would be heterogeneous, containing
# different ListItem types that could be filtered perhaps (an option
# different list item types that could be filtered perhaps (an option
# for selecting all of a given type, for example).
# For sub list items, set selection_target to self (this is a kind of
@ -115,10 +72,10 @@ class ListItem(SelectableItem, BoxLayout):
icon_kwargs = kwargs.copy()
icon_kwargs['text'] = '>'
icon_kwargs['size_hint_x'] = .05
self.icon_button = ListItemSubButton(**icon_kwargs)
self.icon_button = ListItemButton(**icon_kwargs)
# Use the passed in kwargs for the "content" button.
self.content_button = ListItemSubButton(**kwargs)
self.content_button = ListItemButton(**kwargs)
self.add_widget(self.icon_button)
self.add_widget(self.content_button)
@ -197,7 +154,7 @@ class MasterDetailView(GridLayout):
args_converter=args_converter,
selection_mode='single',
allow_empty_selection=False,
cls=ListItem)
cls=CompositeListItem)
self.master_list_view = ListView(adapter=self.list_adapter,
size_hint=(.3, 1.0))
self.add_widget(self.master_list_view)

View File

@ -4,7 +4,7 @@ from kivy.uix.button import Button
from kivy.properties import ObjectProperty, \
NumericProperty, ListProperty, \
StringProperty
from kivy.uix.listview import ListView
from kivy.uix.listview import ListView, ListItemButton
from kivy.adapters.mixins.selection import SingleSelectionObserver, \
SelectableItem
from kivy.adapters.listadapter import ListAdapter
@ -13,29 +13,6 @@ from kivy.adapters.listadapter import ListAdapter
# (the master) and another view (detail view) that gets updated upon
# selection.
# For the master list, we need to create a custom "list item" type that
# subclasses SelectableItem.
class ListItem(SelectableItem, Button):
selected_color = ListProperty([1., 0., 0., 1])
deselected_color = None
def __init__(self, **kwargs):
super(ListItem, self).__init__(**kwargs)
# Set deselected_color to be default Button bg color.
self.deselected_color = self.background_color
def select(self, *args):
self.background_color = self.selected_color
def deselect(self, *args):
self.background_color = self.deselected_color
def __repr__(self):
return self.text
# DetailView is an observer of the selection of the associated list view,
# so SelectionObserver is mixed in, requiring an override of the
# observed_selection_changed() method.
@ -96,7 +73,7 @@ class MasterDetailView(GridLayout):
args_converter=list_item_args_converter,
selection_mode='single',
allow_empty_selection=False,
cls=ListItem)
cls=ListItemButton)
master_list_view = ListView(adapter=list_adapter,
size_hint=(.3, 1.0))
self.add_widget(master_list_view)

View File

@ -3,7 +3,7 @@ from kivy.adapters.listadapter import ListAdapter, \
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.listview import ListView
from kivy.uix.listview import ListView, ListItemButton
from kivy.adapters.mixins.selection import SingleSelectionObserver, \
SelectableItem
from kivy.properties import ListProperty, StringProperty, ObjectProperty
@ -13,30 +13,6 @@ from kivy.properties import ListProperty, StringProperty, ObjectProperty
# to have one list allow multiple selection and the other to show the
# multiple items selected in the first.
# Generic list item will do fine for both list views:
class ListItem(SelectableItem, Button):
selected_color = ListProperty([1., 0., 0., 1])
deselected_color = None
def __init__(self, **kwargs):
super(ListItem, self).__init__(**kwargs)
# Set deselected_color to be default Button bg color.
self.deselected_color = self.background_color
def select(self, *args):
print self.text, 'is now selected'
self.background_color = self.selected_color
def deselect(self, *args):
print self.text, 'is now unselected'
self.background_color = self.deselected_color
def __repr__(self):
return self.text
class MultipleCascadingView(GridLayout):
'''Implementation of a master-detail style view, with a scrollable list
of fruits on the left and the selection in that list on the right in
@ -57,7 +33,7 @@ class MultipleCascadingView(GridLayout):
args_converter=list_item_args_converter,
selection_mode='multiple',
allow_empty_selection=False,
cls=ListItem)
cls=ListItemButton)
fruits_list_view = \
ListView(adapter=fruits_list_adapter,
size_hint=(.2, 1.0))
@ -72,7 +48,7 @@ class MultipleCascadingView(GridLayout):
args_converter=list_item_args_converter,
selection_mode='single',
allow_empty_selection=True,
cls=ListItem)
cls=ListItemButton)
selected_fruits_list_view = \
ListView(adapter=selected_fruits_list_adapter,
size_hint=(.2, 1.0))

View File

@ -25,6 +25,7 @@ Notes:
from kivy.event import EventDispatcher
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.adapters.util import list_item_args_converter
class Adapter(EventDispatcher):
@ -37,6 +38,10 @@ class Adapter(EventDispatcher):
args_converter = ObjectProperty(None)
def __init__(self, **kwargs):
if hasattr(kwargs, 'args_converter'):
self.args_converter = kwargs['args_converter']
else:
self.args_converter = list_item_args_converter
super(Adapter, self).__init__(**kwargs)
if self.cls is None and self.template is None:
raise Exception('A cls or template must be defined')

11
kivy/adapters/util.py Normal file
View File

@ -0,0 +1,11 @@
'''
The default list item args converter for list adapters is this simple function
that takes a string and returns the string as the text argument in a dict,
along with two properties suited for simple text items with height of 25.
[TODO] Might there be other useful converters to put here, with descriptive
names?
'''
list_item_args_converter = lambda x: {'text': x,
'size_hint_y': None,
'height': 25}

View File

@ -7,6 +7,7 @@ import unittest
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.listview import ListView, ListItemButton
from kivy.properties import NumericProperty, ListProperty
from kivy.adapters.mixins.selection import SelectionObserver, SelectableItem
from kivy.adapters.listadapter import ListAdapter
@ -101,26 +102,6 @@ for row in raw_fruit_data:
**dict(zip(descriptors_and_units.keys(), row['data'])))
class FruitListItem(SelectableItem, Button):
selected_color = ListProperty([1., 0., 0., 1])
deselected_color = None
def __init__(self, **kwargs):
super(FruitListItem, self).__init__(**kwargs)
# Set deselected_color to be default Button bg color.
self.deselected_color = self.background_color
def select(self, *args):
self.background_color = self.selected_color
def deselect(self, *args):
self.background_color = self.deselected_color
def __repr__(self):
return self.text
class AdaptersTestCase(unittest.TestCase):
def setUp(self):
@ -134,9 +115,9 @@ class AdaptersTestCase(unittest.TestCase):
args_converter=self.args_converter,
selection_mode='none',
allow_empty_selection=True,
cls=FruitListItem)
cls=ListItemButton)
self.assertEqual(list_adapter.cls, FruitListItem)
self.assertEqual(list_adapter.cls, ListItemButton)
self.assertEqual(list_adapter.args_converter, self.args_converter)
self.assertEqual(list_adapter.template, None)
@ -144,4 +125,4 @@ class AdaptersTestCase(unittest.TestCase):
self.assertTrue(isinstance(apple_data_item, str))
apple_view = list_adapter.get_view(0)
self.assertTrue(isinstance(apple_view, FruitListItem))
self.assertTrue(isinstance(apple_view, ListItemButton))

View File

@ -7,7 +7,7 @@ import unittest
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.listview import ListView
from kivy.uix.listview import ListView, ListItemButton
from kivy.properties import NumericProperty, ListProperty, StringProperty
from kivy.adapters.mixins.selection import SelectionObserver, SelectableItem
from kivy.adapters.listadapter import ListAdapter, SelectableListsAdapter, \
@ -103,26 +103,6 @@ for row in raw_fruit_data:
**dict(zip(descriptors_and_units.keys(), row['data'])))
class FruitListItem(SelectableItem, Button):
selected_color = ListProperty([1., 0., 0., 1])
deselected_color = None
def __init__(self, **kwargs):
super(FruitListItem, self).__init__(**kwargs)
# Set deselected_color to be default Button bg color.
self.deselected_color = self.background_color
def select(self, *args):
self.background_color = self.selected_color
def deselect(self, *args):
self.background_color = self.deselected_color
def __repr__(self):
return self.text
class FruitSelectionObserver(SelectionObserver, Widget):
fruit_name = StringProperty('')
call_count = NumericProperty(0)
@ -147,7 +127,7 @@ class ListAdapterTestCase(unittest.TestCase):
args_converter=self.args_converter,
selection_mode='none',
allow_empty_selection=True,
cls=FruitListItem)
cls=ListItemButton)
self.assertEqual(len(list_adapter.selection), 0)
list_adapter.check_for_empty_selection()
@ -158,7 +138,7 @@ class ListAdapterTestCase(unittest.TestCase):
args_converter=self.args_converter,
selection_mode='single',
allow_empty_selection=True,
cls=FruitListItem)
cls=ListItemButton)
self.assertEqual(len(list_adapter.selection), 0)
list_adapter.check_for_empty_selection()
@ -173,7 +153,7 @@ class ListAdapterTestCase(unittest.TestCase):
args_converter=self.args_converter,
selection_mode='single',
allow_empty_selection=False,
cls=FruitListItem)
cls=ListItemButton)
self.assertEqual(len(list_adapter.selection), 1)
list_adapter.check_for_empty_selection()
@ -184,7 +164,7 @@ class ListAdapterTestCase(unittest.TestCase):
args_converter=self.args_converter,
selection_mode='multiple',
allow_empty_selection=False,
cls=FruitListItem)
cls=ListItemButton)
self.assertEqual(len(list_adapter.selection), 1)
list_adapter.handle_selection(list_adapter.get_view(1))
@ -197,7 +177,7 @@ class ListAdapterTestCase(unittest.TestCase):
args_converter=self.args_converter,
selection_mode='single',
allow_empty_selection=False,
cls=FruitListItem)
cls=ListItemButton)
selection_observer = FruitSelectionObserver(
observed_list_adapter=list_adapter)
@ -230,7 +210,7 @@ class SelectableListsAdapterTestCase(unittest.TestCase):
args_converter=self.args_converter,
selection_mode='single',
allow_empty_selection=False,
cls=FruitListItem)
cls=ListItemButton)
fruit_categories_list_view = \
ListView(adapter=fruit_categories_l_a,
@ -251,7 +231,7 @@ class SelectableListsAdapterTestCase(unittest.TestCase):
args_converter=self.args_converter,
selection_mode='single',
allow_empty_selection=False,
cls=FruitListItem)
cls=ListItemButton)
fruits_list_view = ListView(adapter=fruits_l_a,
size_hint=(.2, 1.0))

View File

@ -7,7 +7,7 @@ import unittest
from kivy.uix.button import Button
from kivy.properties import ListProperty, StringProperty
from kivy.uix.listview import ListView
from kivy.uix.listview import ListView, ListItemButton
from kivy.adapters.mixins.selection import SelectionObserver, SelectableItem
from kivy.adapters.listadapter import ListAdapter
@ -104,32 +104,6 @@ for row in raw_fruit_data:
**dict(zip(descriptors_and_units.keys(), row['data'])))
class FruitListItem(SelectableItem, Button):
selected_color = ListProperty([1., 0., 0., 1])
deselected_color = None
def __init__(self, list_adapter, **kwargs):
self.list_adapter = list_adapter
super(FruitListItem, self).__init__(**kwargs)
# Set deselected_color to be default Button bg color.
self.deselected_color = self.background_color
self.bind(on_release=self.handle_selection)
def handle_selection(self, button):
self.list_adapter.handle_selection(self)
def select(self, *args):
self.background_color = self.selected_color
def deselect(self, *args):
self.background_color = self.deselected_color
def __repr__(self):
return self.text
class AdaptersTestCase(unittest.TestCase):
def setUp(self):
@ -143,7 +117,7 @@ class AdaptersTestCase(unittest.TestCase):
args_converter=self.args_converter,
selection_mode='none',
allow_empty_selection=True,
cls=FruitListItem)
cls=ListItemButton)
self.assertEqual(len(list_adapter.selection), 0)
list_adapter.check_for_empty_selection()
@ -161,7 +135,7 @@ class AdaptersTestCase(unittest.TestCase):
args_converter=self.args_converter,
selection_mode='multiple',
allow_empty_selection=True,
cls=FruitListItem)
cls=ListItemButton)
self.assertEqual(len(list_adapter.selection), 0)
list_adapter.check_for_empty_selection()

View File

@ -1,3 +1,7 @@
'''
'''
'''
List View
===========
@ -6,68 +10,173 @@ List View
The :class:`ListView` widget provides a scrollable/pannable viewport that is
clipped at the scrollview's bounding box, which contains a list of
item_view_instances.
list item view instances.
[TODO]:
:class:`ListView` implements AbstractView as a vertical scrollable list.
From AbstractView we have these properties and methods:
- Initial selection is apparently working in the associated ListAdapter,
but the list view display does not show the initial selection (red, in
example code). After the list view has been clicked for the first manual
selection, the updating of selected items (in red) works.
- Explain why multiple levels of abstraction are needed. (Adapter,
ListAdapter, AbstractView, ListView) -- Tie discussion to inspiration
for Adapter and related classes:
- adapter (an instance of ListAdapter or one of its subclasses here)
http://developer.android.com/reference/android/\
widget/Adapter.html#getView(int,%20android/\
.view.View,%20android.view.ViewGroup)
- item_view_instances, a dict with indices as keys to the list item view
instances created and held in the ListAdapter
- Divider isn't used (yet).
- Consider adding an associated SortableItem mixin, to be used by list
item classes in a manner similar to the SelectableItem mixin.
- Consider a sort_by property. Review the use of the items property.
(Presently items is a list of strings -- are these just the
strings representing the item_view_instances, which are instances of
the provided cls input argument?). If so, formalize and document.
- Work on item_view_instances marked [TODO] in the code.
- set_item_view() and get_item_view() methods to list item view instances
Examples (in examples/widgets):
Basic Example
-------------
- Improve examples:
- Add fruit images.
- Add an example where selection doesn't just change background color
or font, but animates.
The list items you put in a list view can be totally custom, but to have a
simple button, we may use the :class:`ListItem` class.
Other Possibilities:
Here we make a list view with 100 items.
- Consider a horizontally scrolling variant.
- Is it possible to have dynamic item_view height, for use in a
master-detail list view in this manner?
from kivy.adapters.list_adapter import ListAdapter
from kivy.uix.listview import ListItem, ListView
http://www.zkoss.org/zkdemo/grid/master_detail
item_strings = ["Item {0}".format(index) for index in xrange(100)]
(Would this be a new widget called MasterDetailListView, or would the
listview widget having a facility for use in this way?)
# A list view needs a list adapter to provide a mediating service to the
# data, in the case here our item_strings list, passed as the first
# argument. We choose single selection mode. We may also set this for
# allowing multiple selection. We set allow_empty_selection to False so
# that there is always an item selected if at least one is in the list.
# Setting this to true will make the list useful for display only.
# Finally, we pass ListItem as the class (cls) to be instantiated by the
# list adapter for each list item. ListItem is based on Button. When an
# item is selected, its background color will change to red.
list_adapter = ListAdapter(data=item_strings,
selection_mode='single',
allow_empty_selection=False,
cls=ListItem)
(See the list_disclosure.py file as a start.)
# The list view is a simple component. Just give it the list adapter that
# will provide list item views based on its data.
list_view = ListView(adapter=list_adapter)
Custom Composite Example
------------------------
Let's say you would like to make a list view with composite list item views
consisting of a button on the left, a label in the middle, and a second button
on the right. Perhaps the buttons could be made as toggle buttons for two
separate properties pertaining to the label. First, we need to make a custom
list item, which we will base on the required SelectableItem mixin and our
choice of layout, BoxLayout:
from kivy.adapters.list_adapter import ListAdapter
from kivy.adapters.mixins.selection import SelectableItem
from kivy.uix.listview import ListItemButton, ListItemLabel, ListView
class CompositeListItem(SelectableItem, BoxLayout):
# ListItem sublasses Button, which has background_color.
# For a composite list item, we must add this property.
background_color = ListProperty([1, 1, 1, 1])
selected_color = ListProperty([1., 0., 0., 1])
deselected_color = ListProperty([.33, .33, .33, 1])
left_button = ObjectProperty(None)
middle_label = ObjectProperty(None)
right_button = ObjectProperty(None)
def __init__(self, **kwargs):
super(CompositeListItem, self).__init__(**kwargs)
# For the component list items in our composite list item, we want
# their individual selection to select the composite. Here we pass
# an argument called selection_target, setting it to self (this
# composite list item).
self.left_button = ListItemButton(selection_target=self)
self.middle_label = ListItemLabel(selection_target=self)
self.right_button = ListItemButton(selection_target=self)
self.add_widget(self.left_button)
self.add_widget(self.middle_label)
self.add_widget(self.right_button)
def select(self, *args):
self.background_color = self.selected_color
def deselect(self, *args):
self.background_color = self.deselected_color
def __repr__(self):
return self.middle_label.text
# Here we create a list adapter with some item strings, passing our
# CompositeListItem as the list item view class, and then we create a
# list view using this adapter:
item_strings = ["Item {0}".format(index) for index in xrange(100)]
list_adapter = ListAdapter(data=item_strings,
selection_mode='single',
allow_empty_selection=False,
cls=CompositeListItem)
list_view = ListView(adapter=list_adapter)
Using With kv
-------------
[TODO]
Cascading Selection Between Lists
---------------------------------
[TODO]
- Make a separate master-detail example that works like an iphone-style
animated "source list" that has "disclosure" buttons per item_view, on
the right, that when clicked will expand to fill the entire list view
area (useful on mobile devices especially). Similar question as above --
would listview be given expanded functionality or would this become
another kind of "master-detail" widget?)
'''
__all__ = ('ListView', )
from kivy.clock import Clock
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.adapters.mixins.selection import SelectableItem
from kivy.adapters.util import list_item_args_converter
from kivy.uix.abstractview import AbstractView
from kivy.properties import ObjectProperty, DictProperty, NumericProperty
from kivy.properties import ObjectProperty, DictProperty, \
NumericProperty, ListProperty
from kivy.lang import Builder
from math import ceil, floor
class ListItemButton(SelectableItem, Button):
selected_color = ListProperty([1., 0., 0., 1])
deselected_color = None
def __init__(self, **kwargs):
super(ListItemButton, self).__init__(**kwargs)
# Set deselected_color to be default Button bg color.
self.deselected_color = self.background_color
def select(self, *args):
self.background_color = self.selected_color
def deselect(self, *args):
self.background_color = self.deselected_color
def __repr__(self):
return self.text
class ListItemLabel(SelectableItem, Label):
def __init__(self, **kwargs):
super(ListItemLabel, self).__init__(**kwargs)
def select(self, *args):
self.bold = True
def deselect(self, *args):
self.bold = False
def __repr__(self):
return self.text
Builder.load_string('''
<ListView>:
container: container
@ -83,16 +192,6 @@ Builder.load_string('''
class ListView(AbstractView):
'''Implementation of an Abstract View as a vertical scrollable list.
From AbstractView we have these properties and methods:
- adapter (in usage here, a ListAdapter)
- item_view_instances, a dictionary with data item indices as keys
to the item view instances created and held in the ListAdapter
- set_item_view() and get_item_view() methods to item view instances
'''
divider = ObjectProperty(None)
'''[TODO] Not used.
@ -105,10 +204,10 @@ class ListView(AbstractView):
container = ObjectProperty(None)
'''The container is a GridLayout widget held within a ScrollView widget.
(See the associated kv block in the Builder.load_string() setup). Item
view instances managed in the ListAdapter are added to this container. The
container is cleared with a call to contain.clear_widgets() when the list
is rebuilt in the populate() method. A padding Widget instance is also
added as needed, depending on the row height calculations.
view instances managed and provided by the ListAdapter are added to this
container. The container is cleared with a call to clear_widgets() when
the list is rebuilt by the populate() method. A padding Widget instance
is also added as needed, depending on the row height calculations.
'''
row_height = NumericProperty(None)
@ -198,7 +297,6 @@ class ListView(AbstractView):
continue
sizes[index] = item_view.height
container.add_widget(item_view)
else:
available_height = self.height
real_height = 0