from kivy.lang import Builder
from kivy.properties import StringProperty
from kivymd.uix.screen import MDScreen
from kivymd.uix.card import MDCardSwipe
Builder.load_string('''
<SwipeToDeleteItem>:
size_hint_y: None
height: content.height
type_swipe: "auto"
# anchor: "right"
max_swipe_x: .5
on_swipe_complete: app.remove_item(self)
MDCardSwipeLayerBox:
# Content under the card.
MDCardSwipeFrontBox:
# on_press: print(root.text)
ripple_behavior: True
# Content of card.
OneLineListItem:
id: content
text: root.text
height: 50
_no_ripple_effect: True
on_press: print(self.text)
<MyMDScreen>:
MDBoxLayout:
orientation: "vertical"
spacing: "10dp"
MDTopAppBar:
elevation: 2
title: "MDCardSwipe"
ScrollView:
scroll_timeout : 100
MDList:
id: md_list
MDBottomAppBar:
elevation: 2
''')
class SwipeToDeleteItem(MDCardSwipe):
'''Card with `swipe-to-delete` behavior.'''
text = StringProperty()
def on_touch_move(self, touch):
self._distance += touch.dx
expr = False
if self.anchor == "left" and touch.dx >= 0:
expr = abs(self._distance) < self.swipe_distance
elif self.anchor == "right" and touch.dx < 0:
expr = abs(self._distance) > self.swipe_distance
if expr and not self._opens_process:
self._opens_process = True
self._to_closed = False
if self._opens_process:
self.open_progress = max(
min(self.open_progress + touch.dx / self.width, 2.5), 0
)
return False
def on_touch_up(self, touch):
self._distance = 0
if not self._to_closed:
self._opens_process = False
self.complete_swipe()
return False
class MyMDScreen(MDScreen):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.is_dispatched = None
self.touchable = True
self.md_list = self.ids.md_list
def on_touch_down(self, touch):
self.touchable = True
self.is_dispatched = [c.dispatch('on_touch_down', touch) for c in self.md_list.children]
self.touchable = False
return any(self.is_dispatched)
def on_touch_move(self, touch):
self.touchable = False
return any([c.dispatch('on_touch_move', touch) if self.is_dispatched[i] else None for i, c in enumerate(self.md_list.children)])
def on_touch_up(self, touch):
self.touchable = True
return any([c.dispatch('on_touch_up', touch) if self.is_dispatched[i] else None for i, c in enumerate(self.md_list.children)])
class TestCard(MDApp):
def build(self):
my_mdscreen = MyMDScreen()
return my_mdscreen
def on_start(self):
'''Creates a list of cards.'''
self.md_list = self.root.ids.md_list
for i in range(12):
self.md_list.add_widget(
SwipeToDeleteItem(text=f"One-line item {i}")
)
def remove_item(self, instance):
if instance.state == 'opened':
self.md_list.remove_widget(instance)
TestCard().run()