I'm having a recycleview of labels and I would like to change the font size of these labels using MDSlider. I'm not sure if this is even possible. The closest thing I've got is to change the font of the objects retrieved by the method view_adapter.get_visible_view(index)
, which are the objects currently visible if I'm not mistaken. But using the code below which should be doing just that, I'm getting strange behavior as it's changing the font size of all visible labels, but also some of the labels which aren't visible.
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
kv = """
<DailyService>:
bg_color: app.theme_cls.primary_dark
day: ''
service: ''
MDGridLayout:
rows: 2
MDLabel:
id: firstLabelId
halign: 'center'
text: root.day
MDLabel:
id: secondLabelId
halign: 'center'
md_bg_color: root.bg_color
text: root.service
<MainScreen>:
name: 'mainScreen'
rvid: myRv
MDRelativeLayout:
orientation: 'vertical'
MDRecycleView:
viewclass: 'DailyService'
id: myRv
RecycleBoxLayout:
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: 30
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):
recycleViewObj = self.ids['myRv']
index = 0
while (recycleViewObj.view_adapter.get_visible_view(index)):
idList = recycleViewObj.view_adapter.get_visible_view(index).ids
for obj in idList.values():
obj.font_size = str(int(value))+'dp'
index = index + 1
class MyScreenManager(ScreenManager):
def __init__(self, **kwargs):
super(MyScreenManager, self).__init__(**kwargs)
class MyApp(MDApp):
def on_start(self):
data = []
for i in range(10):
data.append({'day': 'DAY','service': 'SERVICE'})
self.root.ids.mainScreenId.rvid.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()
I've also tried using layout_manager along with the view_adapter and it seems to me that I'm able to extract all the objects from the Recycleview, but when attempting to change the font_size nothing happens. So my guess would be that those objects aren't actual objects that I see in my app. Here's the attempt:
def fontSizeSlider(self, value):
recycleViewObj = self.ids['myRv']
opts = recycleViewObj.layout_manager.view_opts
for i in range(len(recycleViewObj.data)):
viewAdapter = recycleViewObj.view_adapter
viewClass = opts[i]['viewclass']
data = recycleViewObj.data[i]
dailyService = viewAdapter.get_view(i, data, viewClass)
for obj in dailyService.ids.values():
print(obj)
obj.font_size = str(int(value))+'dp'
Is it possible to achieve what I want with Recycleview? Just to make myself clear, I would like to change the font of all the labels in the Recycleview (not just visible ones).
You can add a font_size
property to your DailyService
class, and use it to define the font_size
of the Labels
:
<DailyService>:
bg_color: app.theme_cls.primary_dark
day: ''
service: ''
font_size: '15dp'
MDGridLayout:
rows: 2
MDLabel:
id: firstLabelId
halign: 'center'
text: root.day
font_size: root.font_size
MDLabel:
id: secondLabelId
halign: 'center'
md_bg_color: root.bg_color
text: root.service
font_size: root.font_size
Then in your fontSizeSlider()
method, update the font_size
in the data
of the MDRecycleView
instance:
def fontSizeSlider(self, value):
rv = self.ids.myRv
data = rv.data
for v in data:
v['font_size'] = str(int(value)) + 'dp'
rv.refresh_from_data()