Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

back button functionality on android with kivy

in Kivy, when I press the back button on my android device it throws me out of the application. is there a way to return back to the previous screen using the Kivy language and not python? this is what I have written in kivy:

<MyAppClass>:
AnchorLayout:
    anchor_x : 'center'
    anchor_y : 'top'
    ScreenManager:
        size_hint : 1, .9
        id: _screen_manager

        Screen:
            name:'screen1'
            StackLayout:
                # irrelevant code

        Screen:
            name:'screen2'
            StackLayout:
                # irrelevant code

I need to manipulate the screen manager and its screens from python... if I can do so I will be ok with python.

like image 220
toufikovich Avatar asked Nov 20 '13 08:11

toufikovich


People also ask

Can KIVY be used for Android?

You can run Kivy applications on Android, on (more or less) any device with OpenGL ES 2.0 (Android 2.2 minimum). This is standard on modern devices; Google reports the requirement is met by 99.9% of devices.

How does KIVY run on Android?

Kivy is a Python framework, and simply installing it on an Android device the same way as on a desktop machine will do nothing. However, you can compile a Kivy application to a standard Android APK that will run just like a normal java app on (more or less) any device.

What KIVY used for?

Kivy is a free and open source Python framework for developing mobile apps and other multitouch application software with a natural user interface (NUI). It is distributed under the terms of the MIT License, and can run on Android, iOS, Linux, macOS, and Windows.


4 Answers

i guess that i have solved it but should thank both @inclement and @qua-non! your answers guys led me to the right way! so in kv i assume that i gave an id to my screen manager (please refer to my question where i have written the kv code) , in python i should do the following:

    from kivy.core.window import Window
    from kivy.properties import ObjectProperty

    class MyAppClass(FloatLayout):#its a FloatLayout in my case
        _screen_manager=ObjectProperty(None)
        def __init__(self,**kwargs):
            super(MyAppClass,self).__init__(**kwargs)
            #code goes here and add:
            Window.bind(on_keyboard=self.Android_back_click)

        def Android_back_click(self,window,key,*largs):
            if key == 27:
                self._scree_manager.current='screen1'#you can create a method here to cache in a list the number of screens and then pop the last visited screen.
                return True

    class MyApp(App):
        def build(self):
            return MyAppClass()

    if __name__=='__main__':
        MyApp().run()
like image 150
toufikovich Avatar answered Oct 21 '22 12:10

toufikovich


Kivy on android binds the back button to the esc button so binding and listening to esc button in your app would help you handle how your app behaves when the back button is pressed.

In other words in your app when testing it on your desktop listen to the escape key from the system keyboard, this will be automatically be translated to being the back button on your android device. Something like::

def on_start():
    from kivy.base import EventLoop
    EventLoop.window.bind(on_keyboard=self.hook_keyboard)

def hook_keyboard(self, window, key, *largs):
    if key == 27:
       # do what you want, return True for stopping the propagation
       return True 
like image 37
qua-non Avatar answered Oct 21 '22 12:10

qua-non


This is certainly possible. Here's a short example app with the method I use to do this:

from kivy.utils import platform
from kivy.core.window import Window

class ExampleApp(App):
    manager = ObjectProperty()

    def build(self):
        sm = MyScreenManager()
        self.manager = sm
        self.bind(on_start=self.post_build_init)
        return sm

    def post_build_init(self, *args):
        if platform() == 'android':
            import android
            android.map_key(android.KEYCODE_BACK, 1001)

        win = Window
        win.bind(on_keyboard=self.my_key_handler)

    def my_key_handler(self, window, keycode1, keycode2, text, modifiers):
        if keycode1 in [27, 1001]:
            self.manager.go_back()
            return True
        return False

This should give the right basic idea, but a few notes:

  • ScreenManager doesn't keep track of the previous screens, it's up to you to implement this how you like. My example assumes you defined a class MyScreenManager with a go_back method.
  • It might not be necessary to bind to on_start and run post_build_init, this is just how the example I originally used did it (see below). It might be important sometimes though, possibly if the window is not initialised when build() is run, and the original mailing list post suggests the author needed it for some reason.
  • The example listens for keycodes 27 or 1001. As qua-non said while I was writing this, the former listens for esc, so you can get the same behaviour on desktop.
  • I didn't try without the android.map_key line, but it seems like it may not be necessary.
  • You mention you want to use kivy language and not python. You need to do some python to get this result, and I don't see a way around that (it's not really the domain of the kv language). I guess you could shift some stuff to kv by defining a 'go_back' event somewhere and triggering this when the key is pressed, along with binding your screenmanager to watch that event, but it seems like a long way around.

I based my code on the mailing list thread at https://groups.google.com/forum/#!topic/kivy-users/7rOZGMMIFXI . There might be a better way, but this is quite functional.

like image 7
inclement Avatar answered Oct 21 '22 11:10

inclement


Now all the way in 2020 I'm using:

Clock.schedule_once(lambda x: Window.bind(on_keyboard=self.hook_keyboard))

in combination with a similar hook_keyboard method to the other answers, to delay the bind in my build method. Works fine, but none of these other ways ways seemed to work for me anymore.

like image 1
nihilok Avatar answered Oct 21 '22 10:10

nihilok