如何在 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>
- 启用 Plugin.Badge 我在
AssemblyInfo.cs
中添加了这一行: [assembly: ExportRenderer(typeof(TabbedPage), typeof(BadgedTabbedPageRenderer))]
----> Plugin.Badge 它有效,但是我在 MyTabbedPageRenderer.cs
中设置的所有内容不工作
- 如果我不使用,一切正常:
[assembly: ExportRenderer(typeof(TabbedPage), typeof(BadgedTabbedPageRenderer))]
- ---> 这就是我想要的:
求大家帮忙。谢谢
我已经在我的 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"
我想知道自定义 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>
- 启用 Plugin.Badge 我在
AssemblyInfo.cs
中添加了这一行:[assembly: ExportRenderer(typeof(TabbedPage), typeof(BadgedTabbedPageRenderer))]
----> Plugin.Badge 它有效,但是我在MyTabbedPageRenderer.cs
中设置的所有内容不工作
- 如果我不使用,一切正常:
[assembly: ExportRenderer(typeof(TabbedPage), typeof(BadgedTabbedPageRenderer))]
- ---> 这就是我想要的:
求大家帮忙。谢谢
我已经在我的 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"