I have a RecycleView
which consists of labels and a MDSlider
which I use to change font_size
of those labels during runtime. I'm wondering if it's possible to align labels' size to their texture_size
property. Precisely, whenever I change the font_size
which would cause label's texture_size
to overflow its current size, I would want to increase the label size so the text fits. Since labels live inside the RecycleView
, I'm not sure how should I approach the problem. I'm initially setting height
to self.minimum_height
of the RecycleBoxLayout
which I presume should be updated in the process. I noticed that I can manually change the RecycleBoxLayout's
default_size
during runtime, but not sure how exactly I should pass the texture_size
of the label to adjust the size. I tried with on_size
and on_texture
methods to pass the property and use to calculate default_size
, but things get really complicated and I always end up getting gaps between the labels. Ideally I would want the solution that uses some kind of binding of labels sizes/texture (similarly like I already have with the app.fontSize
) so I would get automatic resizing because any manual calculations of RecycleView
properties and it's consequential update significantly slows down my program in the end when testing on Android.
Any ideas?
EDIT: I haven't mentioned it, I'm only interested in the height resizing. Width doesn't matter.
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.screenmanager import Screen
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.properties import StringProperty
kv = """
<MyLabel@MDLabel>:
font_size: app.fontSize
halign: 'center'
# Using these settings would be awesome, but cannot make it happen.
# Or there might be more elegant solution?
#size: self.texture_size
#size_hint_y: None
#text_size: self.width, None
<DailyService>:
day: ''
service: ''
MDGridLayout:
rows: 2
MyLabel:
id: firstLabelId
text: root.day
md_bg_color: app.theme_cls.accent_color
MyLabel:
id: secondLabelId
md_bg_color: app.theme_cls.primary_dark
text: root.service
<MainScreen>:
name: 'mainScreen'
myRv: rvId
MDRelativeLayout:
orientation: 'vertical'
MDRecycleView:
viewclass: 'DailyService'
id: rvId
rbl: rblId
RecycleBoxLayout:
id: rblId
default_size: None, dp(200)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
MDSlider:
color: 'white'
orientation: 'horizontal'
size_hint: (0.2, 0.2)
pos_hint: {"x":0.4, "top": 1}
min: 10
value: 20
max: 150
on_value_normalized: root.fontSizeSlider(self.value)
MyScreenManager:
mainScreen: mainScreenId
MainScreen:
id: mainScreenId
"""
class DailyService(MDBoxLayout):
pass
class MainScreen(Screen):
def __init__(self, **kwargs):
super(MainScreen, self).__init__(**kwargs)
def fontSizeSlider(self, value):
app = MDApp.get_running_app()
app.fontSize = str(int(value)) + 'dp'
self.myRv.refresh_from_data()
class MyScreenManager(ScreenManager):
def __init__(self, **kwargs):
super(MyScreenManager, self).__init__(**kwargs)
class MyApp(MDApp):
fontSize = StringProperty('20dp')
def on_start(self):
data = []
for i in range(10):
data.append({'day': 'DAY\nDAY',
'service': 'SERVICE\nSERVICE'})
self.root.ids.mainScreenId.myRv.data = data
def build(self):
self.theme_cls.theme_style = 'Dark'
self.theme_cls.primary_palette = 'Blue'
self.theme_cls.accent_palette = 'Amber'
return Builder.load_string(kv)
if __name__ == '__main__':
MyApp().run()
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.screenmanager import Screen
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.properties import StringProperty
kv = """
<MyLabel@MDLabel>:
font_size: app.fontSize
halign: 'center'
# Using these settings would be awesome, but cannot make it happen.
# Or there might be more elegant solution?
#size: self.texture_size
#size_hint_y: None
#text_size: self.width, None
<DailyService>:
day: ''
service: ''
MDGridLayout:
rows: 2
size_hint_y:None
height:app.MyHeight
MyLabel:
id: firstLabelId
text: root.day
md_bg_color: app.theme_cls.accent_color
MyLabel:
id: secondLabelId
md_bg_color: app.theme_cls.primary_dark
text: root.service
<MainScreen>:
name: 'mainScreen'
myRv: rvId
MDRelativeLayout:
orientation: 'vertical'
MDRecycleView:
viewclass: 'DailyService'
id: rvId
rbl: rblId
RecycleBoxLayout:
id: rblId
default_size: None, app.MyHeight
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
MDSlider:
color: 'white'
orientation: 'horizontal'
size_hint: (0.2, 0.2)
pos_hint: {"x":0.4, "top": 1}
min: 10
value: 20
max: 150
on_value_normalized: root.fontSizeSlider(self.value)
MyScreenManager:
mainScreen: mainScreenId
MainScreen:
id: mainScreenId
"""
class DailyService(MDBoxLayout):
pass
class MainScreen(Screen):
def __init__(self, **kwargs):
super(MainScreen, self).__init__(**kwargs)
def fontSizeSlider(self, value):
app = MDApp.get_running_app()
app.fontSize = str(int(value)) + 'dp'
app.MyHeight = str( int(value) * 10 ) + 'dp'
self.myRv.refresh_from_data()
class MyScreenManager(ScreenManager):
def __init__(self, **kwargs):
super(MyScreenManager, self).__init__(**kwargs)
class MyApp(MDApp):
fontSize = StringProperty('20dp')
MyHeight = StringProperty('200dp')
def on_start(self):
data = []
for i in range(10):
data.append({'day': 'DAY\nDAY',
'service': 'SERVICE\nSERVICE'})
self.root.ids.mainScreenId.myRv.data = data
def build(self):
self.theme_cls.theme_style = 'Dark'
self.theme_cls.primary_palette = 'Blue'
self.theme_cls.accent_palette = 'Amber'
return Builder.load_string(kv)
if __name__ == '__main__':
MyApp().run()