from kivy.app import App from kivy.lang import Builder from kivy.uix.button import Button from kivy.uix.recycleview import RecycleView from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout from kivy.uix.gridlayout import GridLayout from kivy.uix.popup import Popup from kivy.graphics import Rectangle from kivy.uix.image import Image, AsyncImage from kivy.uix.widget import Widget from kivy.uix.behaviors import ButtonBehavior from kivy.clock import Clock, mainthread from kivy.properties import ObjectProperty from kivy.uix.screenmanager import ScreenManager, Screen from kivy.uix.scrollview import ScrollView from kivy.core.window import Window from kivy.uix.spinner import Spinner from kivy.logger import Logger from kivy.storage.jsonstore import JsonStore from kivy.properties import BooleanProperty, ListProperty, ObjectProperty, NumericProperty, DictProperty, StringProperty # items = [ # {"color":(1, 1, 1, 1), "font_size": "20sp", "text": "white", "input_data": ["some","random","data"]}, # {"color":(.5,1, 1, 1), "font_size": "30sp", "text": "lightblue", "input_data": [1,6,3]}, # {"color":(.5,.5,1, 1), "font_size": "40sp", "text": "blue", "input_data": [64,16,9]}, # {"color":(.5,.5,.5,1), "font_size": "70sp", "text": "gray", "input_data": [8766,13,6]}, # {"color":(1,.5,.5, 1), "font_size": "60sp", "text": "orange", "input_data": [9,4,6]}, # {"color":(1, 1,.5, 1), "font_size": "50sp", "text": "yellow", "input_data": [852,958,123]}, # {"color":(.5,1, 1, 1), "font_size": "30sp", "text": "lightblue", "input_data": [1,6,3]}, # {"color":(.5,.5,1, 1), "font_size": "40sp", "text": "blue", "input_data": [64,16,9]}, # {"color":(.5,.5,.5,1), "font_size": "70sp", "text": "gray", "input_data": [8766,13,6]}, # {"color":(1,.5,.5, 1), "font_size": "60sp", "text": "orange", "input_data": [9,4,6]}, # {"color":(1, 1,.5, 1), "font_size": "50sp", "text": "yellow", "input_data": [852,958,123]} # ] items = [ {"image_link": "https://i.ytimg.com/vi/0Lm5sRu1G9A/hq720.jpg?sqp=-oaymwEZCNAFEJQDSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLC025lwn4RBjkGUVqDZhUgo83_yvQ", "image_desc": "Snowman video", "btn_text": "Play"}, {"image_link": "https://i.ytimg.com/vi/0Lm5sRu1G9A/hq720.jpg?sqp=-oaymwEZCNAFEJQDSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLC025lwn4RBjkGUVqDZhUgo83_yvQ", "image_desc": "Snowman video", "btn_text": "Play"}, {"image_link": "https://i.ytimg.com/vi/0Lm5sRu1G9A/hq720.jpg?sqp=-oaymwEZCNAFEJQDSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLC025lwn4RBjkGUVqDZhUgo83_yvQ", "image_desc": "Snowman video", "btn_text": "Play"}, {"image_link": "https://i.ytimg.com/vi/0Lm5sRu1G9A/hq720.jpg?sqp=-oaymwEZCNAFEJQDSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLC025lwn4RBjkGUVqDZhUgo83_yvQ", "image_desc": "Snowman video", "btn_text": "Play"}, {"image_link": "https://i.ytimg.com/vi/0Lm5sRu1G9A/hq720.jpg?sqp=-oaymwEZCNAFEJQDSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLC025lwn4RBjkGUVqDZhUgo83_yvQ", "image_desc": "Snowman video", "btn_text": "Play"}, {"image_link": "https://i.ytimg.com/vi/0Lm5sRu1G9A/hq720.jpg?sqp=-oaymwEZCNAFEJQDSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLC025lwn4RBjkGUVqDZhUgo83_yvQ", "image_desc": "Snowman video", "btn_text": "Play"}, {"image_link": "https://i.ytimg.com/vi/0Lm5sRu1G9A/hq720.jpg?sqp=-oaymwEZCNAFEJQDSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLC025lwn4RBjkGUVqDZhUgo83_yvQ", "image_desc": "Snowman video", "btn_text": "Play"}, {"image_link": "https://i.ytimg.com/vi/0Lm5sRu1G9A/hq720.jpg?sqp=-oaymwEZCNAFEJQDSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLC025lwn4RBjkGUVqDZhUgo83_yvQ", "image_desc": "Snowman video", "btn_text": "Play"}, {"image_link": "https://i.ytimg.com/vi/0Lm5sRu1G9A/hq720.jpg?sqp=-oaymwEZCNAFEJQDSFXyq4qpAwsIARUAAIhCGAFwAQ==&rs=AOn4CLC025lwn4RBjkGUVqDZhUgo83_yvQ", "image_desc": "Snowman video", "btn_text": "Play"} ] class VideoItem(GridLayout): # this must be GridLayout pass KV = ''' : image_link: "link" image_desc: "text" btn_text: "text" cols: 3 height: self.minimum_height AsyncImage: source: root.image_link height: 400 # custom height size_hint_y: None Label: text: root.image_desc height: 400 # custom height size_hint_y: None Button: height: 400 # custom height text: root.btn_text size_hint_y: None RecycleView: data: [] viewclass: 'VideoItem' RecycleBoxLayout: default_size_hint: 1, None # this must be set default_size: None, 1 # this must be set size_hint_y: None height: self.minimum_height orientation: 'vertical' ''' class Test(App): def build(self): root = Builder.load_string(KV) root.data = [item for item in items] return root Test().run()