using Android.Content; using Android.Views; using Android.Widget; using Google.Android.Material.BottomNavigation; using Google.Android.Material.Tabs; using System; using Xamarin.Forms; using Project.Android.Renderers; using Project.Views; using Xamarin.Forms.Platform.Android; using Xamarin.Forms.Platform.Android.AppCompat; [assembly: ExportRenderer(typeof(TabbedPage), typeof(DashboardTabbedPageRenderer))] namespace project.Android.Renderers { /// /// Dahs board tabbed page renderer. /// public class DashboardTabbedPageRenderer : TabbedPageRenderer { private TabLayout _tabLayout; private TabbedPage _page; private BottomNavigationView _bottomNavigationView; private int _lastItemId = -1; private Context _context; private TextView _badgeView; public DashboardTabbedPageRenderer(Context context) : base(context) { _context = context; } /// /// Ons the element changed. /// /// E. protected override void OnElementChanged(ElementChangedEventArgs e) { base.OnElementChanged(e); if (Element != null) { _tabLayout = (TabLayout)ViewGroup.GetChildAt(1); for (var i = 0; i < Element.Children.Count; i++) { var child = Element.Children[i]; } for (var i = 0; i < ViewGroup.ChildCount; i++) { var layousst = ViewGroup.GetChildAt(i); } } if (e.NewElement != null) { _page = e.NewElement; _page.CurrentPageChanged += Page_CurrentPageChanged; ((DashboardTabPage)e.NewElement).DashboardBadgeEvent += DashboardTabbedPageRenderer_BadgeEvent; } else { _page = e.OldElement; _page.CurrentPageChanged -= Page_CurrentPageChanged; ((DashboardTabPage)e.NewElement).DashboardBadgeEvent -= DashboardTabbedPageRenderer_BadgeEvent; } } void Page_CurrentPageChanged(object sender, EventArgs e) { Device.BeginInvokeOnMainThread(() => { try { //NOTE: BottomNavigationView was getting disposed and crashing the Android app _bottomNavigationView.SelectedItemId = _lastItemId; } catch (ObjectDisposedException disposedExc) { if (_page != null) { //NOTE: If disposed need to unsubscribe the Page because it was infinitely being subscribed to _page.CurrentPageChanged -= Page_CurrentPageChanged; } Console.WriteLine($"DashboardTabbedPageRenderer Disposed Exception: {disposedExc}"); } }); } private void DashboardTabbedPageRenderer_BadgeEvent(object sender, int count) { Device.BeginInvokeOnMainThread(() => { UpdateBadge(count); }); } /// /// Ons the element property changed. /// /// Sender. /// E. protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); if (_tabLayout == null && e.PropertyName == "Renderer") { _tabLayout = (TabLayout)ViewGroup.GetChildAt(1); } if (_tabLayout != null && e.PropertyName == "CurrentPage") { _tabLayout.GetTabAt(1).Select(); } for (var i = 0; i < ViewGroup.ChildCount; i++) { var view = ViewGroup.GetChildAt(i) as global::Android.Widget.RelativeLayout; for (var j = 0; j < view.ChildCount; j++) { var child = view.GetChildAt(j); if (child is BottomNavigationView) { _bottomNavigationView = child as BottomNavigationView; _bottomNavigationView.NavigationItemSelected -= BottomNavigationView_NavigationItemSelected; _bottomNavigationView.NavigationItemSelected += BottomNavigationView_NavigationItemSelected; _bottomNavigationView.NavigationItemReselected -= BottomNavigationView_NavigationItemReselected; _bottomNavigationView.NavigationItemReselected += BottomNavigationView_NavigationItemReselected; } } } } void BottomNavigationView_NavigationItemReselected(object sender, BottomNavigationView.NavigationItemReselectedEventArgs e) { _lastItemId = e.Item.ItemId; _page.CurrentPage = _page.Children[_lastItemId]; } void BottomNavigationView_NavigationItemSelected(object sender, BottomNavigationView.NavigationItemSelectedEventArgs e) { _lastItemId = e.Item.ItemId; _page.CurrentPage = _page.Children[_lastItemId]; } private void UpdateBadge(int count) { try { if (_bottomNavigationView == null) return; if (count == 0) { RemoveBadge(); return; } if (_badgeView == null) { BottomNavigationMenuView view = (BottomNavigationMenuView)_bottomNavigationView.GetChildAt(0); var itemView = (BottomNavigationItemView)view.GetChildAt(0); var badgeLayout = LayoutInflater.From(_context).Inflate(Resource.Layout.CustomTabLayout, itemView, true); _badgeView = badgeLayout.FindViewById(Resource.Id.text_badge); } _badgeView.Visibility = ViewStates.Visible; _badgeView.SetText(count.ToString(), TextView.BufferType.Normal); } catch (Exception ex) { Console.WriteLine(ex); } } private void RemoveBadge() { if (_bottomNavigationView == null) return; if (_badgeView == null) { BottomNavigationMenuView view = (BottomNavigationMenuView)_bottomNavigationView.GetChildAt(0); var itemView = (BottomNavigationItemView)view.GetChildAt(0); var badgeLayout = LayoutInflater.From(_context).Inflate(Resource.Layout.CustomTabLayout, itemView, true); _badgeView = badgeLayout.FindViewById(Resource.Id.text_badge); } _badgeView.Visibility = ViewStates.Gone; _badgeView.SetText("0", TextView.BufferType.Normal); } } }