我正在開發一個Kivy媒體播放器並使用RecycleView顯示我的媒體列表。選擇下一個/上一個Kivy RecycleView按鈕上的行按
我試圖實現的是將現有的行選擇從按鈕選擇更改爲RecycleView列表中的下一行或上一行。
我可以看到LayoutSelectionBehavior類看起來像合適的方法,但我正在努力尋找一種方法來使用它。
下面是從kivy.uix.recycleview例子
# -*- coding: utf-8 -*-
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, StringProperty, NumericProperty
from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
kv = """
<SelectableLabel>:
# Draw a background to indicate selection
canvas.before:
Color:
rgba: (0.4, 0.4, 0.4, 1) if self.selected else (0.5, 0.5, 0.5, 1)
Rectangle:
pos: self.pos
size: self.size
<KivyPlayer>:
canvas:
Color:
rgba: 0.3, 0.3, 0.3, 1
Rectangle:
size: self.size
pos: self.pos
orientation: 'vertical'
BoxLayout:
orientation: 'vertical'
BoxLayout:
Button:
id: next_track
text: "Next Track"
Button:
id: previous_track
text: "Previous Track"
BoxLayout:
RecycleView:
id: media_list
viewclass: 'SelectableLabel'
scroll_type: ['bars', 'content']
scroll_wheel_distance: dp(114)
bar_width: dp(10)
SelectableRecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
# multiselect: True
touch_multiselect: True
spacing: dp(2)
"""
Builder.load_string(kv)
class SelectableRecycleBoxLayout(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_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
if is_selected:
print("selection changed to {0}".format(rv.data[index]))
else:
print("selection removed for {0}".format(rv.data[index]))
class KivyPlayer(BoxLayout):
''' Main Kivy class for creating the initial BoxLayout '''
def __init__(self, **kwargs):
super(KivyPlayer, self).__init__(**kwargs)
# Set media_list data
self.ids.media_list.data = [{'text': str(x)} for x in range(100)]
class KivyApp(App):
def build(self):
return KivyPlayer()
if __name__ == '__main__':
KivyApp().run()
任何建議或協助,將不勝感激修改RecycleView的簡化示例。
感謝您花時間閱讀本文並提供@matt的詳細回覆。您的解決方案運作完美。我會閱讀使用'ids',因爲我以前沒有見過。 SO主持人,如果我應該發表一個新問題,不能確定在回覆中詢問其他問題的政策。 @matt是否有一種從KivyPlayer類的init方法中選擇第一個/下一個節點的簡單方法?如果你在那裏處理,很樂意在#kivy IRC中討論? – campervancoder
我發現了一個hacky的方法,它是使用ButtonBehavior類和trigger_action方法'self.next_track.trigger_action(duration = 0.1)'我懷疑有更清晰的方法:) – campervancoder
您確實需要使用這個時鐘。但是像'Clock.schedule_once(lambda * x:self.ids.controller.select_node(0),0.1)'。但是你應該詢問IRC是否不起作用(我也是'matham')。 – Matt