This comes down to setting the GridLayout's cols
property to 2 if the screen is narrow or 4 if the screen is wider. Here's a short app doing exactly that:
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.lang import Builder
Builder.load_string('''
#:import Window kivy.core.window.Window
<ResponsiveGridLayout>:
cols: 2 if Window.width < 400 else 4
Button:
text: 'button 1'
Button:
text: 'button 2'
Button:
text: 'button 3'
Button:
text: 'button 4'
''')
class ResponsiveGridLayout(GridLayout):
pass
class GridApp(App):
def build(self):
return ResponsiveGridLayout()
if __name__ == "__main__":
GridApp().run()
You should be able to run this on a desktop and see the number of columns dynamically change as you resize the window. The cutoff is 400 pixels.
The important bit is the line cols: 2 if Window.width < 400 else 4
. Since everything to the right of a colon is plain python, this returns 2 or 4 depending on the width of Window (imported at the top). And since cols
is a kivy property, GridLayout can and does monitor it to automatically redo the layout if its value changes.
Edit: And just to be clear, Window.width is also a kivy property, so the kv language automatically binds to it such that cols
will be updated if Window.width changes. That's why resizing the window works.
Of course there is more you might want to do to make this perfect for your own app. For instance, rather than monitoring the width in pixels you may want to use scale-independent units that map to physical width taking into account screen dpi (see kivy.metrics). You may also want to set your GridLayout's height to get larger if it's using two columns/rows, which can be achieved in a similar way.