Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在RecyleView kivy内添加KivyMD扩展面板_Kivy_Kivy Language_Kivymd - Fatal编程技术网

在RecyleView kivy内添加KivyMD扩展面板

在RecyleView kivy内添加KivyMD扩展面板,kivy,kivy-language,kivymd,Kivy,Kivy Language,Kivymd,有人能帮我在RecycleView kivy中添加KivyMD扩展面板吗?因为我在kivy上添加带有“add_widget”的MDExpansionPanel(在旧android中运行)时遇到了性能缓慢的问题 然后我有了将扩展放入RecycleView的想法,但是expansionpanel不能用真正的索引打开 仅供参考,我已经制作了自定义扩展.py文件 扩展.py from kivy.animation import Animation from kivy.lang import Builde

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

然后我有了将扩展放入RecycleView的想法,但是expansionpanel不能用真正的索引打开

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

扩展.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)

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.animation导入动画
从kivy.lang导入生成器
从kivy.metrics导入dp
从kivy.properties导入StringProperty、ObjectProperty、NumericProperty
从kivy.uix.boxlayout导入boxlayout
从kivymd.uix.button导入MDIconButton
从kivymd.uix.list导入(IRightBody、ILeftBody、TwoLineavariconListItem)
从kivymd.uix.selectioncontrol导入MDCheckbox
Builder.load\u字符串(
"""
#:导入图像\u路径kivymd.images\u路径
#:导入md_图标kivymd.icon_定义.md_图标
文本:root.title
辅助文本:root.desc
_无涟漪效应:正确
IconRightSampleWidget:
id:支票
禁用的颜色:[.2、.3、.6、.9]
残疾人士:对
雪佛兰灯:
id:雪佛龙
图标:“V形右”
残疾人士:对
在以下情况之前:
推矩阵
轮换:
角度:self.angle
轴:(0,0,1)
来源:自我中心
在下列情况之后:
流行音乐
尺寸提示:无
高度:dp(68)
填充:dp(0)
盒子布局:
id:box\u项目
尺寸提示:无
高度:root.height
方向:“垂直”
CustomExpansionPanel:
id:item_anim
标题:root.title
desc:root.desc
按下按钮:root。选中打开框(self)
"""
)
类IconRightSampleWidget(ILeftBody,MDCheckbox):
通过
类V形灯光(IRightBody,MDIconButton):
角度=数值属性(0)
类CustomExpansionPanel(TwoLineavariconListItem):
title=StringProperty()
desc=StringProperty()
类CustomMDExpansionPanel(BoxLayout):
content=ObjectProperty()
title=StringProperty()
desc=StringProperty()
定义初始(自我,**kwargs):
超级(CustomMDExpansionPanel,self)。\uuuuuuuuuuuuuuuuuuuuuuuuuu(**kwargs)
自注册事件类型(“打开”)
自注册事件类型(“打开关闭”)
def on_open(自身,*参数):
通过
def on_close(自身,*参数):
通过
def复选框打开(self、instance、CloseAll=False):
按\u当前\u项=False
对于self.parent.children中的框:
如果isinstance(框,CustomMDExpansionPanel):
如果len(box.ids.box\u item.children)=2:
如果实例为box.ids.item\u anim:
按当前项目=真
box.ids.box\u项。删除\u小部件(box.ids.box\u项。子项[0])
chevron=box.ids.box\u item.children[0].ids.chevron
self.anim_雪佛龙(雪佛龙)
self.anim\u resize\u close(框)
自动发送(“开/关”)
打破
如果未按当前项目,则不关闭所有项目:
self.anim_chevron_down()
def动画雪佛龙向下(自):
雪佛龙=self.ids.item_anim.ids.chevron
角度=-90
动画(角度=角度,d=0.2)。开始(V形)
self.anim\u resize\u open\u item()
自动发送(“打开”)
def动画雪佛龙(自身,实例):
角度=0
动画(角度=角度,d=0.2)。开始(实例)
def动画大小调整关闭(自身,方框):
动画(高度=dp(68),d=0.1,t=“立方英寸”)。开始(方框)
def动画大小调整打开项目(自身,*参数):
self.content.name_item=self.title
动画(
高度=self.content.height+dp(70),d=0.2,t=“立方英寸”
)
anim.bind(on_complete=self.add_内容)
动画开始(自我)
def添加内容(自身,*参数):
如果self.content和len(self.ids.box\u item.children)==1:
self.ids.box\u item.add\u小部件(self.content)
main.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)

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()
从kivymd.app导入MDApp作为app
从kivy.lang导入生成器
从kivy.uix.screenmanager导入screenmanager,屏幕
从kivy.properties导入ObjectProperty
从kivy.clock导入时钟
从扩展导入CustomMDExpansionPanel
从时间导入时间
从kivy.uix.boxlayout导入boxlayout
Builder.load\u字符串(
"""
:
回收视图:回收视图
回收审查:
id:recycle\u视图
尺寸提示:1,0.9
viewclass:“CustomMDExpansionPanel”
可循环使用的布局:
id:items\u box
科尔斯:1
默认大小提示:1,无
大小提示:1,无
高度:自身最小高度
"""
)
类容器(BoxLayout):
定义初始(自我,**kwargs):
超级(容器,自身)。\uuuu初始化
类列表屏幕(屏幕):
recycle_view=ObjectProperty(无)
items\u box=ObjectProperty(无)
def on_输入(自):
开始=时间()
容器=[]
对于范围(0,50)内的i:
container.append(container(item='strr'+str(i),index=i))
self.recycle\u view.data.append(
{
“内容”:容器[i],
“标题”:“标题”+str(i),
“描述”:“描述”+str(一)
}
)
休假期间的def(自我):
self.recycle_view.data=[]
类ListApp(应用程序):
sm=屏幕管理器()
屏幕={}
def生成(自):
self.\u创建屏幕()
ListApp.sm.add_小部件(ListApp.screens['list1'])
返回ListApp.sm
定义创建屏幕(自):
ListApp.screens['list1']=ListScreen(name='list1')
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
ListApp().run()
多谢各位