protected override void OnElementChanged(ElementChangedEventArgs <TabbedPage> e) { base.OnElementChanged(e); var activity = Context.GetActivity(); var isDesigner = Context.IsDesignerContext(); var themeContext = isDesigner ? Context : activity; if (e.OldElement != null) { ((IPageController)e.OldElement).InternalChildren.CollectionChanged -= OnChildrenCollectionChanged; } if (e.NewElement != null) { if (IsBottomTabPlacement) { if (_relativeLayout == null) { _relativeLayout = new AWidget.RelativeLayout(Context) { LayoutParameters = new LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent), }; if (_bottomNavigationView != null) { _relativeLayout.RemoveView(_bottomNavigationView); _bottomNavigationView.SetOnNavigationItemSelectedListener(null); } var bottomNavigationViewLayoutParams = new AWidget.RelativeLayout.LayoutParams( LayoutParams.MatchParent, LayoutParams.WrapContent); bottomNavigationViewLayoutParams.AddRule(AWidget.LayoutRules.AlignParentBottom); _bottomNavigationView = new BottomNavigationView(Context) { LayoutParameters = bottomNavigationViewLayoutParams, Id = Platform.GenerateViewId() }; var viewPagerParams = new AWidget.RelativeLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent); viewPagerParams.AddRule(AWidget.LayoutRules.Above, _bottomNavigationView.Id); FormsViewPager pager = _viewPager = CreateFormsViewPager(themeContext, e.NewElement); pager.Id = Platform.GenerateViewId(); pager.AddOnPageChangeListener(this); _relativeLayout.AddView(pager, viewPagerParams); _relativeLayout.AddView(_bottomNavigationView, bottomNavigationViewLayoutParams); AddView(_relativeLayout); } } else { if (_tabLayout == null) { TabLayout tabs; if (FormsAppCompatActivity.TabLayoutResource > 0 && !isDesigner) { tabs = _tabLayout = activity.LayoutInflater.Inflate(FormsAppCompatActivity.TabLayoutResource, null).JavaCast <TabLayout>(); } else { tabs = _tabLayout = new TabLayout(themeContext) { TabMode = TabLayout.ModeFixed, TabGravity = TabLayout.GravityFill } }; FormsViewPager pager = _viewPager = CreateFormsViewPager(themeContext, e.NewElement); pager.Id = Platform.GenerateViewId(); pager.AddOnPageChangeListener(this); AddView(pager); AddView(tabs); } } OnChildrenCollectionChanged(null, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); TabbedPage tabbedPage = e.NewElement; if (tabbedPage.CurrentPage != null) { ScrollToCurrentPage(); } _previousPage = tabbedPage.CurrentPage; ((IPageController)tabbedPage).InternalChildren.CollectionChanged += OnChildrenCollectionChanged; UpdateBarBackgroundColor(); UpdateBarTextColor(); UpdateItemIconColor(); if (!isDesigner) { UpdateSwipePaging(); UpdateOffscreenPageLimit(); } } }
protected override void OnLayout(bool changed, int l, int t, int r, int b) { FormsViewPager pager = _viewPager; Context context = Context; var width = r - l; var height = b - t; if (IsBottomTabPlacement) { if (width <= 0 || height <= 0) { return; } _relativeLayout.Measure( MeasureSpec.MakeMeasureSpec(width, MeasureSpecMode.Exactly), MeasureSpec.MakeMeasureSpec(height, MeasureSpecMode.Exactly)); pager.Measure(MeasureSpecFactory.MakeMeasureSpec(width, MeasureSpecMode.AtMost), MeasureSpecFactory.MakeMeasureSpec(height, MeasureSpecMode.AtMost)); if (width > 0 && height > 0) { PageController.ContainerArea = new Rectangle(0, 0, context.FromPixels(width), context.FromPixels(height - _bottomNavigationView.MeasuredHeight)); SetNavigationRendererPadding(0, _bottomNavigationView.MeasuredHeight); pager.Layout(0, 0, width, b); // We need to measure again to ensure that the tabs show up _relativeLayout.Measure( MeasureSpec.MakeMeasureSpec(width, MeasureSpecMode.Exactly), MeasureSpec.MakeMeasureSpec(height, MeasureSpecMode.Exactly)); _relativeLayout.Layout(0, 0, _relativeLayout.MeasuredWidth, _relativeLayout.MeasuredHeight); } } else { TabLayout tabs = _tabLayout; tabs.Measure(MeasureSpecFactory.MakeMeasureSpec(width, MeasureSpecMode.Exactly), MeasureSpecFactory.MakeMeasureSpec(height, MeasureSpecMode.AtMost)); var tabsHeight = 0; if (tabs.Visibility != ViewStates.Gone) { //MinimumHeight is only available on API 16+ if ((int)System.Maui.Maui.SdkInt >= 16) { tabsHeight = Math.Min(height, Math.Max(tabs.MeasuredHeight, tabs.MinimumHeight)); } else { tabsHeight = Math.Min(height, tabs.MeasuredHeight); } } pager.Measure(MeasureSpecFactory.MakeMeasureSpec(width, MeasureSpecMode.AtMost), MeasureSpecFactory.MakeMeasureSpec(height, MeasureSpecMode.AtMost)); if (width > 0 && height > 0) { PageController.ContainerArea = new Rectangle(0, context.FromPixels(tabsHeight), context.FromPixels(width), context.FromPixels(height - tabsHeight)); SetNavigationRendererPadding(tabsHeight, 0); pager.Layout(0, 0, width, b); // We need to measure again to ensure that the tabs show up tabs.Measure(MeasureSpecFactory.MakeMeasureSpec(width, MeasureSpecMode.Exactly), MeasureSpecFactory.MakeMeasureSpec(tabsHeight, MeasureSpecMode.Exactly)); tabs.Layout(0, 0, width, tabsHeight); UpdateTabBarTranslation(pager.CurrentItem, 0); } } base.OnLayout(changed, l, t, r, b); }
protected override void Dispose(bool disposing) { if (disposing && !_disposed) { _disposed = true; if (Element != null) { PageController.InternalChildren.CollectionChanged -= OnChildrenCollectionChanged; foreach (Page pageToRemove in Element.Children) { TeardownPage(pageToRemove); } } RemoveAllViews(); if (_viewPager != null) { _viewPager.ClearOnPageChangeListeners(); _viewPager.Adapter.Dispose(); _viewPager.Dispose(); _viewPager = null; } if (_tabLayout != null) { _tabLayout.ClearOnTabSelectedListeners(); _tabLayout.Dispose(); _tabLayout = null; } if (_bottomNavigationView != null) { _bottomNavigationView.SetOnNavigationItemSelectedListener(null); _bottomNavigationView.Dispose(); _bottomNavigationView = null; } if (_relativeLayout != null) { _relativeLayout.Dispose(); _relativeLayout = null; } if (Element != null) { foreach (Page pageToRemove in Element.Children) { IVisualElementRenderer pageRenderer = Platform.GetRenderer(pageToRemove); pageRenderer?.Dispose(); pageToRemove.ClearValue(Platform.RendererProperty); } } _previousPage = null; } base.Dispose(disposing); }