【问题标题】:Add KivyMD Expansion Panel inside RecyleView kivy在 RecyleView kivy 中添加 KivyMD 扩展面板
【发布时间】:2020-10-21 07:44:07
【问题描述】:

任何人都可以帮助我如何在 RecycleView kivy 中添加 KivyMD 扩展面板?因为我在 kivy 上添加带有“add_widget”的 MDExpansionPanel 时遇到性能缓慢的问题(在旧 android 中运行)。

然后我有想法将Expansion放入RecycleView,但是expansionpanel无法以真实索引打开。

仅供参考,我已经制作了自定义扩展.py 文件

expansion.py

from kivy.animation import Animation
from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import StringProperty, ObjectProperty, NumericProperty
from kivy.uix.boxlayout import BoxLayout
from kivymd.uix.button import MDIconButton
from kivymd.uix.list import (IRightBody, ILeftBody, TwoLineAvatarIconListItem)
from kivymd.uix.selectioncontrol import MDCheckbox

Builder.load_string(
    """
#:import images_path kivymd.images_path
#:import md_icons kivymd.icon_definitions.md_icons
<CustomExpansionPanel>
    text: root.title
    secondary_text: root.desc
    _no_ripple_effect: True

    IconRightSampleWidget:
        id: check
        disabled_color: [.2, .3, .6, .9]
        disabled: True

    ChevronRight:
        id: chevron
        icon: 'chevron-right'
        disabled: True

        canvas.before:
            PushMatrix
            Rotate:
                angle: self.angle
                axis: (0, 0, 1)
                origin: self.center
        canvas.after:
            PopMatrix

<CustomMDExpansionPanel>
    size_hint_y: None
    height: dp(68)
    padding:dp(0)

    BoxLayout:
        id: box_item
        size_hint_y: None
        height: root.height
        orientation: 'vertical'

        CustomExpansionPanel:
            id: item_anim
            title: root.title
            desc: root.desc
            on_press: root.check_open_box(self)
"""
)


class IconRightSampleWidget(ILeftBody, MDCheckbox):
    pass


class ChevronRight(IRightBody, MDIconButton):
    angle = NumericProperty(0)


class CustomExpansionPanel(TwoLineAvatarIconListItem):
    title = StringProperty()
    desc = StringProperty()


class CustomMDExpansionPanel(BoxLayout):
    content = ObjectProperty()
    title = StringProperty()
    desc = StringProperty()

    def __init__(self, **kwargs):
        super(CustomMDExpansionPanel, self).__init__(**kwargs)
        self.register_event_type("on_open")
        self.register_event_type("on_close")

    def on_open(self, *args):
        pass

    def on_close(self, *args):
        pass

    def check_open_box(self, instance,CloseAll=False):
        press_current_item = False
        for box in self.parent.children:
            if isinstance(box, CustomMDExpansionPanel):
                if len(box.ids.box_item.children) == 2:
                    if instance is box.ids.item_anim:
                        press_current_item = True
                    box.ids.box_item.remove_widget(box.ids.box_item.children[0])
                    chevron = box.ids.box_item.children[0].ids.chevron
                    self.anim_chevron_up(chevron)
                    self.anim_resize_close(box)
                    self.dispatch("on_close")
                    break

        if not press_current_item and not CloseAll:
            self.anim_chevron_down()
    
    def anim_chevron_down(self):
        chevron = self.ids.item_anim.ids.chevron
        angle = -90
        Animation(angle=angle, d=0.2).start(chevron)
        self.anim_resize_open_item()
        self.dispatch("on_open")

    def anim_chevron_up(self, instance):
        angle = 0
        Animation(angle=angle, d=0.2).start(instance)

    def anim_resize_close(self, box):
        Animation(height=dp(68), d=0.1, t="in_cubic").start(box)

    def anim_resize_open_item(self, *args):
        self.content.name_item = self.title
        anim = Animation(
            height=self.content.height + dp(70), d=0.2, t="in_cubic"
        )
        anim.bind(on_complete=self.add_content)
        anim.start(self)

    def add_content(self, *args):
        if self.content and len(self.ids.box_item.children) == 1:
            self.ids.box_item.add_widget(self.content)

ma​​in.py

from kivymd.app import MDApp as App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import ObjectProperty
from kivy.clock import Clock
from expansion import CustomMDExpansionPanel
from time import time
from kivy.uix.boxlayout import BoxLayout

Builder.load_string(
    """
<ListScreen>:
    recycle_view: recycle_view
    RecycleView:
        id: recycle_view
        size_hint: 1, 0.9
        viewclass: "CustomMDExpansionPanel"
        RecycleGridLayout:
            id: items_box
            cols:1
            default_size_hint: 1, None
            size_hint: 1, None
            height:self.minimum_height
"""
)
class Container(BoxLayout):
    def __init__(self,**kwargs):
        super(Container,self).__init__()
class ListScreen(Screen):

    recycle_view = ObjectProperty(None)
    items_box = ObjectProperty(None)

    def on_enter(self):
        start = time()
        container = []
        for i in range(0,50):
            container.append(Container(item='strrr'+str(i), index=i))
            self.recycle_view.data.append(
                {
                    'content':container[i],
                    'title':'title'+str(i), 
                    'desc':'desc'+str(i)
                }
            )
    def on_leave(self):
        self.recycle_view.data = []

class ListApp(App):

    sm = ScreenManager()
    screens = {}

    def build(self):
        self.__create_screens()
        ListApp.sm.add_widget(ListApp.screens['list1'])
        return ListApp.sm

    def __create_screens(self):
        ListApp.screens['list1'] = ListScreen(name='list1')

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

谢谢

【问题讨论】:

    标签: kivy kivy-language kivymd


    【解决方案1】:

    据我了解,如果您尝试在 RecycleView 中添加您的扩展面板

    这是一个如何做到这一点的示例代码

    from kivy.lang import Builder
    
    from kivymd.app import MDApp
    from kivymd.uix.boxlayout import MDBoxLayout
    from kivymd.uix.expansionpanel import MDExpansionPanel, MDExpansionPanelThreeLine
    from kivymd import images_path
    
    KV = """
    <Content>
        adaptive_height: True
    
        TwoLineIconListItem:
            text: "(050)-123-45-67"
            secondary_text: "Mobile"
    
    
    RecycleView:
    
        MDGridLayout:
            id: box
            cols: 1
            adaptive_height: True
    """
    
    
    class Content(MDBoxLayout):
        """Custom content."""
    
    
    class Test(MDApp):
        def build(self):
            return Builder.load_string(KV)
    
        def on_start(self):
            for i in range(10):
                self.root.ids.box.add_widget(
                    MDExpansionPanel(
                        icon=f"{images_path}kivymd.png",
                        content=Content(),
                        panel_cls=MDExpansionPanelThreeLine(
                            text="Text",
                            secondary_text="Secondary text",
                            tertiary_text="Tertiary text",
                        ),
                    )
                )
    
    
    Test().run()
    
    

    请在提问前参考文档 :) 因为它可以解决您 90% 的问题

    同时编辑您的问题并明确说明您的问题:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-07-21
      • 1970-01-01
      • 1970-01-01
      • 2022-10-06
      • 1970-01-01
      • 2021-10-12
      • 2019-10-09
      • 1970-01-01
      相关资源
      最近更新 更多