RecycleView - Remove Item

729 views
Skip to first unread message

Fari Tigar

unread,
Apr 19, 2017, 5:10:36 AM4/19/17
to Kivy users support
Hi,

I have two RecycleViews, and my goal is to be able to move items between these.
At the beginning List 1 is populated with values 0,1,2 , when I select a value it is added to other list, I click on every item of List 1, 
so List2 is populated also with 0,1,2, this works fine.

When I click on List2: I want to delete the selected ITEM of this list, which does not work as expected. Depending on the selection multiple items are deleted, to be precise the selected and all subsequent items, based on index, are removed from the list.
After that, it is not possible to add new items to List2. 

Based on the log, I assume, that I have to handle the is_selected of the items in List2, but I am not sure how to do that.

Thanks for any help.


Steps:
1 :SelectableLabel:                   choose values 2,1,0
2: SelectableLabel_selected:      select 2
3: SelectableLabel::                   select 2

Log:
#startup
SelectableLabel: index: 0, is_selected False
SelectableLabel: index: 1, is_selected False
SelectableLabel: index: 0, is_selected False
SelectableLabel: index: 1, is_selected False
SelectableLabel: index: 2, is_selected False
SelectableLabel: index: 0, is_selected False
SelectableLabel: index: 1, is_selected False
SelectableLabel: index: 2, is_selected False
SelectableLabel: index: 2, is_selected True

#Step 1:
# 2 selected
SelectableLabel: index: 2, is_selected True
SelectableLabel_Selected: index: 0, is_selected False 

#1 selected
SelectableLabel: index: 1, is_selected True
SelectableLabel_Selected: index: 0, is_selected False
SelectableLabel_Selected: index: 1, is_selected False

#0 selected
SelectableLabel: index: 1, is_selected False
SelectableLabel: index: 0, is_selected True
SelectableLabel_Selected: index: 0, is_selected False
SelectableLabel_Selected: index: 1, is_selected False
SelectableLabel_Selected: index: 2, is_selected False

#Step2: This step deletes all data as index 0 is selected everytime
SelectableLabel_Selected: index: 0, is_selected True
RV_selected: remove_data executed with value: {'text': '2'}
SelectableLabel_Selected: index: 0, is_selected True
RV_selected: remove_data executed with value: {'text': '1'}
SelectableLabel_Selected: index: 1, is_selected False
SelectableLabel_Selected: index: 0, is_selected True
RV_selected: remove_data executed with value: {'text': '0'}


#Step 3: Select 2 in first list:
SelectableLabel: index: 0, is_selected False
SelectableLabel: index: 2, is_selected True
SelectableLabel_Selected: index: 0, is_selected True
RV_selected: remove_data executed with value: {'text': '2'}

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
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
from kivy.core.window import Window

Window.clearcolor = (0, 0.5, 0.5, 1)

Builder.load_string('''

 

<AppRoot>:
    orientation:"horizontal"
    rv:rv
    rv_selected:rv_selected
    BoxLayout:
        orientation:"vertical"
        size_hint:1,1
        Label:
            text:"SelectableLabel:"
            size_hint:1,0.2
        RV:
            id:rv
            size_hint:1,0.8
    BoxLayout:
        size_hint:1,1
        orientation:"vertical"
        Label:
            text:"SelectableLabel_Selected:"
            size_hint:1,0.2
           
        RV_Selected:
            id:rv_selected
            size_hint:1,0.8

 
<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: False
        touch_multiselect: False
       
<RV_Selected>:
    viewclass: 'SelectableLabel_Selected'
    SelectableRecycleBoxLayout_Selected:
        default_size: None, dp(56)
        default_size_hint: 1, None
        size_hint_y: None
        height: self.minimum_height
        orientation: 'vertical'
        multiselect: False
        touch_multiselect: False
''')


class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
                                 
RecycleBoxLayout):
   
''' Adds selection and focus behaviour to the view. '''

class SelectableRecycleBoxLayout_Selected(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_data_changed(self):
       
pass
    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
       
print("SelectableLabel: index: {}, is_selected {}".format(index, is_selected))
       
if is_selected:
            app
= App.get_running_app()
            app
.root.rv_selected.data.append(rv.data[index])
       
else:
           
pass
            #print("SelectableLabel: 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(3)]

   
def add_data(self,value):
       
self.data.append(value)
       
print("RV: add_data executed with value: {}".format(value))

class SelectableLabel_Selected(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_Selected, self).refresh_view_attrs(
            rv
, index, data)

   
def on_touch_down(self, touch):
       
''' Add selection on touch down '''
        if super(SelectableLabel_Selected, 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. '''
        print("SelectableLabel_Selected: index: {}, is_selected {}".format(index,is_selected))
       
self.selected = is_selected
       
if is_selected:
            rv
.remove_data(rv.data[index])
           
#print("SelectableLabel_Selected: selection changed to {0}".format(rv.data[index]))
        else:
           
pass
            #print("SelectableLabel_Selected: selection removed for {0}".format(rv.data[index]))


class RV_Selected(RecycleView):
   
def __init__(self, **kwargs):
       
super(RV_Selected, self).__init__(**kwargs)

   
def remove_data(self,value):
       
"""value of dictionary, eg. 3 """
        new_selected_dict  = [elem for elem in self.data if  value["text"]  not  in elem["text"]]
       
self.data=new_selected_dict
       
print("RV_selected: remove_data executed with value: {}".format(value))

class AppRoot(BoxLayout):
   
pass

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

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


recyleview.PNG

Kevin Diaz

unread,
May 17, 2017, 1:34:16 PM5/17/17
to Kivy users support
After you delete the item you need to add this line of code: 
rv.layout_manager.clear_selection()
After you delete the item it selects the next item in the list deleting it and so forth. 
Reply all
Reply to author
Forward
0 new messages