protected virtual void OnPageSelected(int position) { if (_selecting) { return; } var shellSection = ShellSection; var visibleItems = SectionController.GetItems(); // This mainly happens if all of the items that are part of this shell section // vanish. Android calls `OnPageSelected` with position zero even though the view pager is // empty if (visibleItems.Count >= position) { return; } var shellContent = visibleItems[position]; if (shellContent == shellSection.CurrentItem) { return; } var stack = shellSection.Stack.ToList(); bool result = ShellController.ProposeNavigation(ShellNavigationSource.ShellContentChanged, (ShellItem)shellSection.Parent, shellSection, shellContent, stack, true); if (result) { UpdateCurrentItem(shellContent); } else if (shellSection?.CurrentItem != null) { var currentPosition = visibleItems.IndexOf(shellSection.CurrentItem); _selecting = true; // Android doesn't really appreciate you calling SetCurrentItem inside a OnPageSelected callback. // It wont crash but the way its programmed doesn't really anticipate re-entrancy around that method // and it ends up going to the wrong location. Thus we must invoke. _viewPager.Post(() => { if (currentPosition < _viewPager.ChildCount && _toolbarTracker != null) { _viewPager.SetCurrentItem(currentPosition, false); UpdateCurrentItem(shellSection.CurrentItem); } _selecting = false; }); } }
void TabLayoutMediator.ITabConfigurationStrategy.OnConfigureTab(TabLayout.Tab tab, int position) { if (_selecting) { return; } tab.SetText(new String(SectionController.GetItems()[position].Title)); // TODO : Find a way to make this cancellable var shellSection = ShellSection; var shellContent = SectionController.GetItems()[position]; if (shellContent == shellSection.CurrentItem) { return; } var stack = shellSection.Stack.ToList(); bool result = ShellController.ProposeNavigation(ShellNavigationSource.ShellContentChanged, (ShellItem)shellSection.Parent, shellSection, shellContent, stack, true); if (result) { UpdateCurrentItem(shellContent); } else if (shellSection?.CurrentItem != null) { var currentPosition = SectionController.GetItems().IndexOf(shellSection.CurrentItem); _selecting = true; // Android doesn't really appreciate you calling SetCurrentItem inside a OnPageSelected callback. // It wont crash but the way its programmed doesn't really anticipate re-entrancy around that method // and it ends up going to the wrong location. Thus we must invoke. Device.BeginInvokeOnMainThread(() => { if (currentPosition < _viewPager.ChildCount && _toolbarTracker != null) { _viewPager.SetCurrentItem(currentPosition, false); UpdateCurrentItem(shellSection.CurrentItem); } _selecting = false; }); } }