dewango / BottomNavigationBarXF

Bottom Navigation Bar for Xamarin Forms
MIT License
187 stars 97 forks source link

Enables badges on Android with bindable badge count and badge color #57

Closed henningms closed 7 years ago

henningms commented 7 years ago

This pull request includes some changes to the BottomBarPageRenderer and Extension classes to allow simple badge support on Android.

You can add a badge count and color using the new attached properties BadgeCount and BadgeColor. BadgeColor is bindable but the badge color won't change dynamically due to limitations in the underlying BottomBarBadge class.

I have not included iOS badge support although this can be achieved with a custom TabbedPage renderer using the same attached properties.

henningms commented 7 years ago

Might help with #30 and #8

nbsoftware commented 6 years ago

As a thank for this, here is a - really basic - iOS renderer that implements BadgeCount, as for a start. To add to your iOS project. For anyone that might need it.

using BottomBar.XamarinForms;
using System.ComponentModel;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(BottomBarPage), typeof(BottomBarPageRenderer))]
namespace fipacapp.iOS
{
    public class BottomBarPageRenderer : TabbedRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if (e.NewElement != null)
            {
                BottomBarPage bottomBarPage = e.NewElement as BottomBarPage;
                AddPropertyChangedHandlersForPages();
            }
        }

        void AddPropertyChangedHandlersForPages()
        {
            BottomBarPage bottomBarPage = Element as BottomBarPage;
            foreach (var page in bottomBarPage.Children)
            {
                page.PropertyChanged += OnPagePropertyChanged;
            }
        }

        void OnPagePropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == BottomBarPageExtensions.BadgeCountProperty.PropertyName)
            {
                var page = (Page)sender;
                var badgeCount = BottomBarPageExtensions.GetBadgeCount(page);
                var tabIndex = Tabbed.Children.IndexOf(page);
                TabBar.Items[tabIndex].BadgeValue = (badgeCount == 0 ? null : badgeCount.ToString());
            }
        }
    }
}
C0D3On3 commented 6 years ago

Great job @henningms! @nbsoftware thank you for the iOS example.

nbsoftware commented 6 years ago

You are welcome. Since then I have fixed a few important things in the main project, among them the fact that the badges weren't persistent when switching tabs in Android... See it there https://github.com/nbsoftware/BottomNavigationBarXF

C0D3On3 commented 6 years ago

Sweet @nbsoftware ! Thank you.

Nixon-Joseph commented 6 years ago

Hey @nbsoftware, I'm using your ios renderer, and am still not seeing any badges on ios. I checked out your branch of this project, and didn't see an ios portion there, nor do any of the commits seem to be yours. https://github.com/nbsoftware/BottomNavigationBarXF is the proper project right?

nbsoftware commented 6 years ago

Hi,

Well yes, but you need to check the netStd2 branch - this is where I commit my changes for now.

Lastly, I did not add any iOS renderer to the base project (BottomNavigationBarXF), rather I added it in my app's project, in the iOS one.

Hope it clarifies.

Nixon-Joseph commented 6 years ago

@nbsoftware Holy quick response Batman!

Thanks for the quick reply. I did the same, just adding the renderer manually into my ios project. I'm never getting into if (e.PropertyName == BottomBarPageExtensions.BadgeCountProperty.PropertyName) though. just seems to be getting width and height property changes.

I see your netStd2 branch, and I'm going to take a look at that as well. Though it shouldn't have any effect on ios badges.

EDIT Found the issue, just needed to implement an override on ViewWillAppear that runs through all the pages and checks for badge counts. I was just trying to set them too early.

`protected override void OnElementChanged(VisualElementChangedEventArgs e) { base.OnElementChanged(e);

        if (e.NewElement != null)
        {
            BottomBarPage bottomBarPage = e.NewElement as BottomBarPage;
            AddPropertyChangedHandlersForPages();
        }
    }

    void AddPropertyChangedHandlersForPages()
    {
        BottomBarPage bottomBarPage = Element as BottomBarPage;
        foreach (var page in bottomBarPage.Children)
        {
            page.PropertyChanged += OnPagePropertyChanged;

            UpdateTabBadge(page);
        }
    }

    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);

        BottomBarPage bottomBarPage = Element as BottomBarPage;
        foreach (var page in bottomBarPage.Children)
        {
            UpdateTabBadge(page);
        }
    }

    void OnPagePropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == BottomBarPageExtensions.BadgeCountProperty.PropertyName)
        {
            UpdateTabBadge((Page)sender);
        }
    }

    private void UpdateTabBadge(Page page) {
        if (TabBar != null && TabBar.Items != null)
        {
            var badgeCount = BottomBarPageExtensions.GetBadgeCount(page);
            var tabIndex = Tabbed.Children.IndexOf(page);
            TabBar.Items[tabIndex].BadgeValue = (badgeCount == 0 ? null : badgeCount.ToString());
        }
    }`