KivyMD
KivyMD copied to clipboard
NavigationRailItems does not appear on the further screen
Description of the Bug
I am using two NavigationRails in two different screens. The NavigationRailItems only appear on the first page.
Code
To change page:
- Open drawer by clicking menu button
- Click on the Item for the page of your choice
- Click to the right of the drawer to close it
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
<NavigationRailBase@MDNavigationRail>
anchor: "top"
<MenuButton@MDNavigationRailMenuButton>
on_release: app.open_menu(self)
<RailItemBase@MDNavigationRailItem>
icon: "language-%s" % self.text
<PageBase@MDScreen>
rail_item_1: ""
rail_item_2: ""
MDBoxLayout:
orientation: "vertical"
MDLabel:
adaptive_height: True
text: root.name
MDBoxLayout:
NavigationRailBase:
MenuButton:
RailItemBase:
text: root.rail_item_1
RailItemBase:
text: root.rail_item_2
MDScreen:
main_sm: main_screen_manager.__self__
menu: menu.__self__
MDNavigationLayout:
ScreenManager:
id: main_screen_manager
PageBase:
name: "First Page"
rail_item_1: "python"
rail_item_2: "javascript"
PageBase:
name: "Second Page"
rail_item_1: "cpp"
rail_item_2: "swift"
MDNavigationDrawer:
id: menu
MDNavigationDrawerMenu:
MDNavigationDrawerItem:
text: "First Page"
icon: "page-first"
on_release: app.switch_page(self)
MDNavigationDrawerItem:
text: "Second Page"
icon: "page-last"
on_release: app.switch_page(self)
'''
class Example(MDApp):
def build(self):
return Builder.load_string(KV)
def switch_page(self, drawer_item):
self.root.main_sm.current = drawer_item.text
def open_menu(self, *args):
self.root.menu.set_state("open")
Example().run()
Screenshots
If I change the anchor property of the NavigationRail to "center" or "bottom" (line 6) the NavigationRailItems appear and everything works as expected.
"""
<NavigationRailBase@MDNavigationRail>
anchor: "center"
"""
Versions
- OS: Windows 10
- Python: 3.10
- Kivy: 2.1.0
- KivyMD: 1.0.0.dev0
@j4ggr Your sample code does not demonstrate the problem.
@j4ggr Shorten your example and remove all unnecessary.
Shorten your example and remove all unnecessary.
Done, please excuse the long example before.
Your sample code does not demonstrate the problem.
Yes it does, look at the screenshots. These were made when executing the code above.
How far are you with the analysis?
@j4ggr I haven't looked at this issue...
I investigated the problem further and found that the y-positions of the rail items on the second page are negative.
In the case described above (anchor == 'top'
and menu button added), the positions of the RailItems in the method set_pos_panel_items
of the MDNavigationRail
class become dependent on the y-position of the menu button.
However, at the time this method is called, the y position of the menu button of second page is negative (-3.0).
Now if I update the RailItem positions by calling the set_pos_menu_fab_buttons
of the MDNavigationRail
class after I switch screens, the items appear on the second page as well. The method requires an interval parameter, although it is not used further within the method. This is probably because the method is called via Clock.schedule_once
(an *args
would actually suffice here). For this reason I give it a 0. I also adjusted the PageBase class a bit (an ID for the NavigationRail). The updated code looks like this:
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
<NavigationRailBase@MDNavigationRail>
anchor: "top"
<MenuButton@MDNavigationRailMenuButton>
on_release: app.open_menu(self)
<RailItemBase@MDNavigationRailItem>
icon: "language-%s" % self.text
<PageBase@MDScreen>
rail_item_1: ""
rail_item_2: ""
MDBoxLayout:
orientation: "vertical"
MDLabel:
adaptive_height: True
text: root.name
MDBoxLayout:
NavigationRailBase:
id: navigation_rail
MenuButton:
RailItemBase:
text: root.rail_item_1
RailItemBase:
text: root.rail_item_2
MDScreen:
main_sm: main_screen_manager.__self__
menu: menu.__self__
MDNavigationLayout:
ScreenManager:
id: main_screen_manager
PageBase:
name: "First Page"
rail_item_1: "python"
rail_item_2: "javascript"
PageBase:
name: "Second Page"
rail_item_1: "cpp"
rail_item_2: "swift"
MDNavigationDrawer:
id: menu
MDNavigationDrawerMenu:
MDNavigationDrawerItem:
text: "First Page"
icon: "page-first"
on_release: app.switch_page(self)
MDNavigationDrawerItem:
text: "Second Page"
icon: "page-last"
on_release: app.switch_page(self)
'''
class Example(MDApp):
def build(self):
app = Builder.load_string(KV)
return app
def switch_page(self, drawer_item):
self.root.main_sm.current = drawer_item.text
screen = self.root.main_sm.current_screen
screen.ids['navigation_rail'].set_pos_menu_fab_buttons(0)
def open_menu(self, *args):
self.root.menu.set_state("open")
Example().run()
Furthermore, the positions of the items are not updated when the window size changes. For example, if you reduce the height of the window, the items are pushed up outside the window.