如何在 Xamarin 中导出渲染器多个 TabbedPage

How to ExportRenderer Multiple TabbedPage in Xamarin

我想知道自定义 TabbedPageRenderer 问题。我在 Xamarin iOS 中创建了一个文件 MyTabbedPageRenderer.cs。我在这里设置的一切都很好。直到我使用 Plugin.Badge。我已经在 Project Xamarin iOS 中安装和配置:AssemblyInfo.cs add: [assembly: ExportRenderer(typeof(TabbedPage), typeof(BadgedTabbedPageRenderer))].

是的,它接受徽章。然而,我设置的所有内容:MyTabbedPageRenderer.cs 变得毫无用处。

我尝试将 BadgedTabbedPageRenderer.cs here 中的内容移动到 MyTabbedPageRenderer.cs 中。我将 [assembly: ExportRenderer(typeof(TabbedPage), typeof(BadgedTabbedPageRenderer))] 更改为 [assembly: ExportRenderer(typeof(TabbedPage), typeof(MyTabbedPageRenderer))]。然而还是不行。

MyTabbedPageRenderer.cs

[assembly: ExportRenderer(typeof(TabbedPage), typeof(MyTabbedPageRenderer))]
namespace xxxx.iOS
{
    internal class MyTabbedPageRenderer : TabbedRenderer
    {
        private bool _initialized;
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            //TabBar.ClipsToBounds = true;
            TabBar.TintColor = UIColor.Gray;
            TabBar.BarTintColor = UIColor.White;
            TabBar.BackgroundColor = UIColor.White;

            MessagingCenter.Subscribe<object, int>(this, "Add", (obj, index) => {
                TabBar.addItemBadge(index);
            });
            MessagingCenter.Subscribe<object, int>(this, "Remove", (obj, index) => {
                TabBar.removeItemBadge(index);
            });
        }

        public override void ViewWillAppear(bool animated)
        {
            if (!_initialized)
            {
                if (TabBar?.Items == null)
                    return;

                foreach (var item in TabBar.Items)
                {
                    item.Image = ScalingImageToSize(item.Image, new CGSize(20, 20)); // set the size here as you want 
                }

                var tabs = Element as TabbedPage;

                if (tabs != null)
                {
                    for (int i = 0; i < TabBar.Items.Length; i++)
                    {
                        UpdateItem(TabBar.Items[i], tabs.Children[i].Icon, tabs.Children[i].StyleId);
                    }
                }

                _initialized = true;
            }

            base.ViewWillAppear(animated);
        }
        private void UpdateItem(UITabBarItem item, string icon, string badgeValue)
        {
            if (item == null) return;

            if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
            {
                //change icon select
                if (icon.EndsWith(".png"))
                    icon = icon.Replace(".png", "_selected.png");
                else
                    icon += "_selected";

                item.SelectedImage = UIImage.FromBundle(icon);
                item.SelectedImage.AccessibilityIdentifier = icon;
                item.SelectedImage = ScalingImageToSize(item.SelectedImage, new CGSize(20, 20)); // set the size here as you want 
                //change icon select


                UITabBarAppearance app = new UITabBarAppearance();
                app.ConfigureWithOpaqueBackground();
                app.BackgroundColor = UIColor.Clear;

                app.StackedLayoutAppearance.Normal.TitleTextAttributes = new UIStringAttributes() { Font = UIFont.FromName("Roboto Medium", 12), ForegroundColor = Color.FromHex("#808080").ToUIColor() };
                app.StackedLayoutAppearance.Selected.TitleTextAttributes = new UIStringAttributes() { Font = UIFont.FromName("Roboto Medium", 13), ForegroundColor = Color.FromHex("#00AA13").ToUIColor() };
                item.StandardAppearance = app;

                if (UIDevice.CurrentDevice.CheckSystemVersion(15, 0))
                {
                    item.ScrollEdgeAppearance = item.StandardAppearance;
                }
            }

        }
        public UIImage ScalingImageToSize(UIImage sourceImage, CGSize newSize)
        {

            if (UIScreen.MainScreen.Scale == 2.0) //@2x iPhone 6 7 8 
            {
                UIGraphics.BeginImageContextWithOptions(newSize, false, 2.0f);
            }


            else if (UIScreen.MainScreen.Scale == 3.0) //@3x iPhone 6p 7p 8p...
            {
                UIGraphics.BeginImageContextWithOptions(newSize, false, 3.0f);
            }

            else
            {
                UIGraphics.BeginImageContext(newSize);
            }

            sourceImage.Draw(new CGRect(0, 0, newSize.Width, newSize.Height));

            UIImage newImage = UIGraphics.GetImageFromCurrentImageContext();

            UIGraphics.EndImageContext();

            return newImage;

        }
    }

    public static class TabbarExtensions
    {

        readonly static int tabBarItemTag = 9999;
        public static void addItemBadge(this UITabBar tabbar, int index)
        {
            if (tabbar.Items != null && tabbar.Items.Length == 0) return;

            if (index >= tabbar.Items.Length) return;

            removeItemBadge(tabbar, index);

            var badgeView = new UIView();
            badgeView.Tag = tabBarItemTag + index;
            badgeView.Layer.CornerRadius = 3;
            badgeView.BackgroundColor = UIColor.Red;

            var tabFrame = tabbar.Frame;
            var percentX = (index + 0.56) / tabbar.Items.Length;
            var x = percentX * tabFrame.Width;
            var y = tabFrame.Height * 0.1;
            badgeView.Frame = new CoreGraphics.CGRect(x, y, 7, 7);
            tabbar.AddSubview(badgeView);
        }

        public static bool removeItemBadge(this UITabBar tabbar, int index)
        {
            foreach (var subView in tabbar.Subviews)
            {
                if (subView.Tag == tabBarItemTag + index)
                {
                    subView.RemoveFromSuperview();
                    return true;
                }
            }

            return false;
        }
    }
}

更新

MainView.xaml

<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            BackgroundColor="#fff"
            xmlns:plugin="clr-namespace:Plugin.Badge.Abstractions;assembly=Plugin.Badge.Abstractions"
            xmlns:views="clr-namespace:xxx.Views"
            x:Class="xxx.Views.MainView">
    <!--Pages can be added as references or inline-->
    <views:Page1 Title="Page 1" IconImageSource="homeicon" BackgroundColor="#fff"/>
    <views:Page2 Title="Page 2" IconImageSource="feeds" BackgroundColor="#fff"/>
    <views:Page3 Title="Page 3" IconImageSource="moneys" BackgroundColor="#fbfbfb" />
    <views:Page4 Title="Page 4" IconImageSource="chats" BackgroundColor="#fff" plugin:TabBadge.BadgeColor="Red" 
        plugin:TabBadge.BadgeText="1"/>
    <views:Page5 Title="Page 5" IconImageSource="usericon" BackgroundColor="#fff"/>
</TabbedPage>
  1. 启用 Plugin.Badge 我在 AssemblyInfo.cs 中添加了这一行: [assembly: ExportRenderer(typeof(TabbedPage), typeof(BadgedTabbedPageRenderer))] ----> Plugin.Badge 它有效,但是我在 MyTabbedPageRenderer.cs 中设置的所有内容不工作

  1. 如果我不使用,一切正常:[assembly: ExportRenderer(typeof(TabbedPage), typeof(BadgedTabbedPageRenderer))]

  1. ---> 这就是我想要的:

求大家帮忙。谢谢

我已经在我的 side.The 徽章效果上进行了测试,效果很好,以下是可能会给您一些见解的步骤。

如您所述,可以通过为 TabbedPage 创建自定义渲染器来实现:

Step1: 将BadgedTabbedPageRenderer.cshere中的内容移动到MyTabbedPageRenderer.cs

步骤 2:在 AssemblyInfo.cs 和 MyTabbedPageRenderer.cs.[=12 中添加 [assembly: ExportRenderer(typeof(TabbedPage), typeof(MyTabbedPageRenderer))] =]

Step3:在你要实现子页面徽章效果的页面中添加两行

plugin:TabBadge.BadgeColor="Red" 
plugin:TabBadge.BadgeText="1"