Kivy recycleview 滚动不流畅
Kivy recycleview not scrolling smoothly
我正在使用 kivy2.0.0 开发一个音乐播放器移动应用程序,在该应用程序中有一个播放列表屏幕,其中包含超过 100 个 mdboxlayout 名为“MusicListItem”的小部件。
我的应用程序有这 2 个问题:
- 滚动部分滚动不流畅,在 android 设备上滚动时有时会出现 select 问题
- 我想要当我 select 一个特定的项目时,调用一个函数并将那个 selected 项目的 MDIconButton 的图标更改为 'pause'。
这是我的 .py 文件
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.core.window import Window
from kivy.properties import StringProperty, ObjectProperty
from kivymd.theming import ThemableBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.screen import MDScreen
from kivymd.uix.behaviors import RectangularRippleBehavior
from kivy.clock import Clock
Builder.load_file('playlist.kv')
KV = """
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManager:
transition: FadeTransition()
Playlist:
name: "playlist screen"
"""
class Playlist(ThemableBehavior, MDScreen):
rv = ObjectProperty()
def __init__(self, **kwargs):
super().__init__(**kwargs)
Clock.schedule_once(self._finish_init)
def music_list(self):
return ['audio '+str(i) for i in range(1, 121)]
def _finish_init(self, dt):
self.set_list_musics()
self.ids.rv.data[0]["icon"] = 'pause'
def set_list_musics(self):
"""Builds a list of audios for the screen Playlist."""
print(self.ids)
def add_music_item(num, sura, secText, icon):
self.ids.rv.data.append(
{
"viewclass": "MusicListItem",
"number": num,
"text": sura,
"secondary_text": secText,
"icon": icon,
"callback": lambda x:x})
for i in range(len(self.music_list())):
music = self.music_list()
add_music_item(str(i+1), music[i], '00:00:00', 'play')
class MusicListItem(ThemableBehavior, RectangularRippleBehavior, MDBoxLayout):
text = StringProperty()
secondary_text = StringProperty()
number = StringProperty()
icon = StringProperty()
class Mp3Player(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def build(self):
self.theme_cls.primary_palette = "Purple"
self.theme_cls.theme_style = "Dark"
return Builder.load_string(KV)
if '__main__' == __name__:
Mp3Player().run()
.kv 文件
#: import gch kivy.utils.get_color_from_hex
<Playlist>
md_bg_color: gch("#5D1049")
MDGridLayout:
cols: 1
MDToolbar:
left_action_items: [["menu", lambda x: x]]
right_action_items: [["magnify", lambda x: x]]
elevation: 10
md_bg_color: 75/255, 6/255, 54/255, 1
title: 'Playlist'
pos_hint: {'top':1}
MDBoxLayout:
orientation: 'vertical'
RecycleView:
id: rv
viewclass: 'MusicListItem'
RecycleBoxLayout:
padding: dp(10)
default_size: None, dp(60)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
<MusicListItem>
size_hint_y: None
padding: dp(14)
height: dp(60)
canvas:
Color:
rgba:
self.theme_cls.divider_color
Line:
points: (root.x+dp(10), root.y, root.x+self.width-dp(10)-0, root.y)
MDBoxLayout:
orientation: "horizontal"
pos_hint: {"center_x": .5, "center_y": .5}
MDBoxLayout:
orientation: 'horizontal'
MDBoxLayout:
orientation: 'vertical'
size_hint_x: .2
MDLabel:
text: root.number
font_style: "H6"
adaptive_height: True
MDLabel:
size_hint_y: .3
MDBoxLayout:
orientation: 'vertical'
MDLabel:
text: root.text
font_style: "Subtitle2"
adaptive_height: True
MDLabel:
text: root.secondary_text
font_style: "Caption"
theme_text_color: "Hint"
adaptive_height: True
MDIconButton:
icon: root.icon
如有任何帮助,我们将不胜感激
首先,我没有发现滚动问题。
其次,为了 select RecycleView
中的特定项目,您需要在该特定项目(viewclass)中有一些类似按钮的行为,当与之交互时会触发一些动作。
因此,您修改后的 MusicListItem
现在应该看起来像,
class MusicListItem(ThemableBehavior, RectangularRippleBehavior, ButtonBehavior, MDBoxLayout):
text = StringProperty()
secondary_text = StringProperty()
number = StringProperty()
icon = StringProperty()
def on_release(self, *args):
self.icon = "pause"
print(f"Selected item no. {self.number}")
请记住在实例级别触发任何操作。
我正在使用 kivy2.0.0 开发一个音乐播放器移动应用程序,在该应用程序中有一个播放列表屏幕,其中包含超过 100 个 mdboxlayout 名为“MusicListItem”的小部件。
我的应用程序有这 2 个问题:
- 滚动部分滚动不流畅,在 android 设备上滚动时有时会出现 select 问题
- 我想要当我 select 一个特定的项目时,调用一个函数并将那个 selected 项目的 MDIconButton 的图标更改为 'pause'。
这是我的 .py 文件
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.core.window import Window
from kivy.properties import StringProperty, ObjectProperty
from kivymd.theming import ThemableBehavior
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.screen import MDScreen
from kivymd.uix.behaviors import RectangularRippleBehavior
from kivy.clock import Clock
Builder.load_file('playlist.kv')
KV = """
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
ScreenManager:
transition: FadeTransition()
Playlist:
name: "playlist screen"
"""
class Playlist(ThemableBehavior, MDScreen):
rv = ObjectProperty()
def __init__(self, **kwargs):
super().__init__(**kwargs)
Clock.schedule_once(self._finish_init)
def music_list(self):
return ['audio '+str(i) for i in range(1, 121)]
def _finish_init(self, dt):
self.set_list_musics()
self.ids.rv.data[0]["icon"] = 'pause'
def set_list_musics(self):
"""Builds a list of audios for the screen Playlist."""
print(self.ids)
def add_music_item(num, sura, secText, icon):
self.ids.rv.data.append(
{
"viewclass": "MusicListItem",
"number": num,
"text": sura,
"secondary_text": secText,
"icon": icon,
"callback": lambda x:x})
for i in range(len(self.music_list())):
music = self.music_list()
add_music_item(str(i+1), music[i], '00:00:00', 'play')
class MusicListItem(ThemableBehavior, RectangularRippleBehavior, MDBoxLayout):
text = StringProperty()
secondary_text = StringProperty()
number = StringProperty()
icon = StringProperty()
class Mp3Player(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def build(self):
self.theme_cls.primary_palette = "Purple"
self.theme_cls.theme_style = "Dark"
return Builder.load_string(KV)
if '__main__' == __name__:
Mp3Player().run()
.kv 文件
#: import gch kivy.utils.get_color_from_hex
<Playlist>
md_bg_color: gch("#5D1049")
MDGridLayout:
cols: 1
MDToolbar:
left_action_items: [["menu", lambda x: x]]
right_action_items: [["magnify", lambda x: x]]
elevation: 10
md_bg_color: 75/255, 6/255, 54/255, 1
title: 'Playlist'
pos_hint: {'top':1}
MDBoxLayout:
orientation: 'vertical'
RecycleView:
id: rv
viewclass: 'MusicListItem'
RecycleBoxLayout:
padding: dp(10)
default_size: None, dp(60)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
<MusicListItem>
size_hint_y: None
padding: dp(14)
height: dp(60)
canvas:
Color:
rgba:
self.theme_cls.divider_color
Line:
points: (root.x+dp(10), root.y, root.x+self.width-dp(10)-0, root.y)
MDBoxLayout:
orientation: "horizontal"
pos_hint: {"center_x": .5, "center_y": .5}
MDBoxLayout:
orientation: 'horizontal'
MDBoxLayout:
orientation: 'vertical'
size_hint_x: .2
MDLabel:
text: root.number
font_style: "H6"
adaptive_height: True
MDLabel:
size_hint_y: .3
MDBoxLayout:
orientation: 'vertical'
MDLabel:
text: root.text
font_style: "Subtitle2"
adaptive_height: True
MDLabel:
text: root.secondary_text
font_style: "Caption"
theme_text_color: "Hint"
adaptive_height: True
MDIconButton:
icon: root.icon
如有任何帮助,我们将不胜感激
首先,我没有发现滚动问题。
其次,为了 select RecycleView
中的特定项目,您需要在该特定项目(viewclass)中有一些类似按钮的行为,当与之交互时会触发一些动作。
因此,您修改后的 MusicListItem
现在应该看起来像,
class MusicListItem(ThemableBehavior, RectangularRippleBehavior, ButtonBehavior, MDBoxLayout):
text = StringProperty()
secondary_text = StringProperty()
number = StringProperty()
icon = StringProperty()
def on_release(self, *args):
self.icon = "pause"
print(f"Selected item no. {self.number}")
请记住在实例级别触发任何操作。