Kivy RecycleView - 如何使用键盘输入滚动?

时间:2017-05-11 13:46:14

标签: scroll keyboard android-recyclerview kivy

如何使用键盘滚动RecycleView?

我想使用向上/向下键来上下移动当前选择并将其保留在视口中。

对于奖励积分,我希望页面向上/向下翻页键一次滚动页面。

到目前为止,我有一个有效的循环视图和键盘输入,但无法确定如何连接它们。

import subprocess

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.video import Video
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import BooleanProperty
from kivy.uix.recycleboxlayout import RecycleBoxLayout
#from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.behaviors import FocusBehavior
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.config import Config

Config.set('graphics', 'width', '1680')
Config.set('graphics', 'height', '1050')
#Config.set('graphics', 'fullscreen', 'auto')
from kivy.core.window import Window
Window.fullscreen = True

Builder.load_string('''
<MyVideo>:
    state: "play"
    options:  {'eos': 'loop'}
<SelectableLabel>:
    # Draw a background to indicate selection
    list_id : app.root.ids["list_id"]
    canvas.before:
        Color:
            rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1)
        Rectangle:
            pos: self.pos
            size: self.size
    #size: 500,500
<RV>:
    viewclass: 'SelectableLabel'
    SelectableRecycleBoxLayout:
        padding: 20
        default_size: None, dp(150)
        default_size_hint: 1, None
        size_hint_y: None
        #size_hint_x: 1
        allow_stretch: True
        height: self.minimum_height
        #width: 500 #self.minimum_width
        orientation: 'vertical'
        multiselect: False
        touch_multiselect: False
<Mame>:
    orientation: "horizontal"
    RV:
        id: list_id
        video_id : video_id
        index: 0
    BoxLayout:
        orientation: "vertical"
        Image:
            allow_stretch: True
            keep_ratio: True
            size_hint_y: None
            size_hint_x: None
            width: self.parent.width
            height: self.parent.width/self.image_ratio
            source: "M:\MAME\marquees\%s.png"  % list_id.data[list_id.index]["game"]
        MyVideo:
            id: video_id
            allow_stretch: True
            #keep_ratio: False
            #size_hint_y: None
            #size_hint_x: None
            #width: self.parent.width
            #height: self.parent.width/self.image_ratio
            source : "V:\%s.mp4"  % list_id.data[list_id.index]["game"]
        Image:
            allow_stretch: True
            keep_ratio: True
            size_hint_y: None
            size_hint_x: None
            width: self.parent.width
            height: self.parent.width/self.image_ratio
            source : "M:\MAME\cpanel\%s.png"  % list_id.data[list_id.index]["game"]
    Image:
        source : "M:\MAME\cabinets\%s.png"  % list_id.data[list_id.index]["game"]
''')

class MyVideo(Video):
    def _do_video_load(self, *largs):
        try:
            return super(MyVideo, self)._do_video_load(largs)
        except:
            return

class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior,
                                 RecycleBoxLayout):
    ''' Adds selection and focus behaviour to the view. '''



class SelectableLabel(RecycleDataViewBehavior, Image):
    ''' 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:
            if touch.is_double_tap:
                #self.selectable = False
                self.list_id.launch(self.index)
                return
            else:
                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:
            self.list_id.index = index
            #print("selection changed to {0}".format(rv.data[index]))
        else:
            pass
            #print("selection removed for {0}".format(rv.data[index]))


class RV(RecycleView):
    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        self._keyboard = Window.request_keyboard(
            self._keyboard_closed, self, 'text')
        self._keyboard.bind(on_key_down=self._on_keyboard_down)
        f = open('golden.ini','r')
        lines = f.readlines()
        f.close()
        self.data = [{'source': "M:\MAME\marquees\%s.png"  % x.strip(), 'game': x.strip(), 'text': x.strip().capitalize()} for x in lines]

    def _keyboard_closed(self):
        print('My keyboard have been closed!')
        self._keyboard.unbind(on_key_down=self._on_keyboard_down)
        self._keyboard = None

    def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
        print('The key', keycode, 'have been pressed')
        print(' - text is %r' % text)
        print(' - modifiers are %r' % modifiers)

        # Keycode is composed of an integer + a string
        # If we hit escape, release the keyboard
        #if keycode[1] == 'escape':
        #    keyboard.release()
        if keycode[1] == 'up':
            if self.index > 0:
                self.index = self.index -1
        elif keycode[1] == 'down':
            if self.index < len(self.data)-1:
                self.index = self.index + 1


        # Return True to accept the key. Otherwise, it will be used by
        # the system.
        return True

    def launch(self,index):
        self.video_id.state = "stop"
        Window.minimize()
        #subprocess.Popen([r"C:\MAME\mame.exe", self.data[index].get("game")],cwd=r"C:\MAME")
        subprocess.call([r"C:\MAME\mame.exe", self.data[index].get("game")],cwd=r"C:\MAME")

        Window.fullscreen = True
        Window.restore()
        self.video_id.state = "play"

class Mame(BoxLayout):

    pass

class TestApp(App):
    def build(self):
        return Mame()

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

0 个答案:

没有答案