我正在构建一个简单的应用程序,它有3个选项卡,每个选项卡都有一个图标和一个文本。我基于我的代码的示例项目存在于这里:
我发现的唯一问题是,它对选项卡头使用像素化的图像,我想将其更改为SVG资源文件。
我添加了一个FFImageLoading库,并从这里添加了svg支持。
我设法将一个图像添加到一个选项卡内容页面中,但我没有看到我试图在标题中看到的svg图像。
到目前为止,这是我的代码:
TodayPage.xaml.cs
public partial class TodayPage : ContentPage
{
public TodayPage()
{
InitializeComponent();
InitializeComponent();
// IconImageSource = "today.png"; <-- this will show the pixilated image
IconImageSource = SvgImageSource.FromResource("today.svg"); //<--not working
Title = "Today";
}
}
TodayPage.xaml
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:forms="clr-namespace:FFImageLoading.Svg.Forms;assembly=FFImageLoading.Svg.Forms"
x:Class="TabsApp.TodayPage">
<ContentPage.Content>
<StackLayout>
<forms:SvgCachedImage WidthRequest="200" HeightRequest="200" Source="resource://TabsApp.Resources.today.svg"/>
<Label Text="Today's appointments go here going" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
MainPage.xaml
<?xml version="1.0" encoding="UTF-8"?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TabsApp;assembly=TabsApp"
x:Class="TabsApp.MainPage">
<local:TodayPage />
<NavigationPage Title="Schedule" IconImageSource="schedule.png">
<x:Arguments>
<local:SchedulePage />
</x:Arguments>
</NavigationPage>
<local:SettingPage />
</TabbedPage>
谢谢
编辑
多亏了Leon,我成功地在Android中加载了svg文件。我仍然很难在iOS中加载svg文件。
我设法在iOS中创建了一个自定义选项卡呈现器,下面是代码:
[assembly: ExportRenderer(typeof(TabPage), typeof(PageTabRenderer))]
namespace TabsApp.iOS
{
[Foundation.Preserve(AllMembers = true)]
public class PageTabRenderer : TabbedRenderer
{
protected override async Task<Tuple<UIImage, UIImage>> GetIcon(Page page)
{
var navigationPage = page as NavigationPage;
if (navigationPage != null && navigationPage.CurrentPage != null)
{
var imageSource = navigationPage.IconImageSource == null ? navigationPage.CurrentPage.IconImageSource : navigationPage.IconImageSource;
return await this.GetNativeUIImage(imageSource);
}
return await this.GetNativeUIImage(page.IconImageSource);
}
private async Task<Tuple<UIImage, UIImage>> GetNativeUIImage(ImageSource imageSource)
{
var imageicon = await GetNativeImageAsync(imageSource);
return new Tuple<UIImage, UIImage>(imageicon, null);
}
private async Task<UIImage> GetNativeImageAsync(ImageSource imageSource)
{
if (imageSource is FileImageSource fileImage && fileImage.File.Contains(".svg"))
{
var imageicon = await ImageService.Instance.LoadFile(fileImage.File).WithCustomDataResolver(new SvgDataResolver(15, 15, true)).AsUIImageAsync();
return imageicon.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
}
else
{
var imageicon = await GetUIImage(imageSource);
return imageicon.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
}
}
private Task<UIImage> GetUIImage(ImageSource imageSource)
{
var handler = GetImageSourceHandler(imageSource);
return handler.LoadImageAsync(imageSource);
}
private static IImageSourceHandler GetImageSourceHandler(ImageSource source)
{
IImageSourceHandler sourceHandler = null;
if (source is UriImageSource)
sourceHandler = new ImageLoaderSourceHandler();
else if (source is FileImageSource)
sourceHandler = new FileImageSourceHandler();
else if (source is StreamImageSource)
sourceHandler = new StreamImagesourceHandler();
else if (source is FontImageSource)
sourceHandler = new FontImageSourceHandler();
return sourceHandler;
}
}
}
这是我的mainpage.xaml
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TabsApp;assembly=TabsApp"
x:Class="TabsApp.MainPage">
<local:TodayPage />
<NavigationPage Title="Schedule" IconImageSource="today1.svg">
<x:Arguments>
<local:SchedulePage />
</x:Arguments>
</NavigationPage>
<local:SettingPage />
</TabbedPage>
我还复制了TabPage类,但没有看到svg图标的加载。我试着调试它,似乎从来没有调用过GetIcon。
编辑2 *
在更多地处理代码之后,我设法弄明白了。如果有人对实现类似的设计感兴趣
main.xaml
<?xml version="1.0" encoding="UTF-8"?>
<custom:TabPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:TabsApp;assembly=TabsApp"
xmlns:custom="clr-namespace:TabsApp.custom;assembly=TabsApp"
x:Class="TabsApp.MainPage"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
android:TabbedPage.ToolbarPlacement="Bottom"
android:TabbedPage.IsSmoothScrollEnabled="True"
android:TabbedPage.IsSwipePagingEnabled="False"
xmlns:iOS="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
xmlns:ffimageloadingsvg="clr-namespace:FFImageLoading.Svg.Forms;assembly=FFImageLoading.Svg.Forms"
iOS:Page.UseSafeArea="true" NavigationPage.HasNavigationBar="False"
BarTextColor="{DynamicResource SecondaryTextColor}" UnselectedTabColor="Black" SelectedTabColor="Blue"
NavigationPage.HasBackButton="False">
<local:TodayPage IconImageSource="{x:OnPlatform Android=ic_today, iOS=today-24px.svg}"/>
<local:SchedulePage IconImageSource="{x:OnPlatform Android=ic_schedule, iOS=schedule-24px.svg}"/>
<local:SettingPage IconImageSource="{x:OnPlatform Android=ic_settings, iOS=settings-24px.svg}"/>
</custom:TabPage>
重要的是要注意两件事: IconImageSource将根据平台的不同而改变,当选择选项卡项时,SelectedTabColor将是安卓和iOS的色调。
您需要像精益编写的那样将svg文件转换为可绘制的向量文件,并将它们放在/drawable文件夹中。
至于iOS,您需要添加一个自定义选项卡呈现器--这是我使用的一个:
[assembly: ExportRenderer(typeof(TabPage), typeof(PageTabRenderer))]
namespace TabsApp.iOS
{
[Foundation.Preserve(AllMembers = true)]
public class PageTabRenderer : TabbedRenderer
{
readonly nfloat imageYOffset = 7.0f;
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
if (TabBar.Items != null)
{
foreach (var item in TabBar.Items)
{
item.Title = null;
item.ImageInsets = new UIEdgeInsets(imageYOffset, 0, -imageYOffset, 0);
}
}
}
protected override async Task<Tuple<UIImage, UIImage>> GetIcon(Page page)
{
var navigationPage = page as NavigationPage;
if (navigationPage != null && navigationPage.CurrentPage != null)
{
var imageSource = navigationPage.IconImageSource == null ? navigationPage.CurrentPage.IconImageSource : navigationPage.IconImageSource;
return await this.GetNativeUIImage(imageSource);
}
return await this.GetNativeUIImage(page.IconImageSource);
}
private async Task<Tuple<UIImage, UIImage>> GetNativeUIImage(ImageSource imageSource)
{
var imageicon = await GetNativeImageAsync(imageSource);
return new Tuple<UIImage, UIImage>(imageicon, null);
}
private async Task<UIImage> GetNativeImageAsync(ImageSource imageSource)
{
if (imageSource is FileImageSource fileImage && fileImage.File.Contains(".svg"))
{
var imageicon = await ImageService.Instance.LoadFile(fileImage.File).WithCustomDataResolver(new SvgDataResolver(15, 15, true)).AsUIImageAsync();
return imageicon.ImageWithRenderingMode(UIImageRenderingMode.Automatic);
}
else
{
var imageicon = await GetUIImage(imageSource);
return imageicon.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
}
}
private Task<UIImage> GetUIImage(ImageSource imageSource)
{
var handler = GetImageSourceHandler(imageSource);
return handler.LoadImageAsync(imageSource);
}
private static IImageSourceHandler GetImageSourceHandler(ImageSource source)
{
IImageSourceHandler sourceHandler = null;
if (source is UriImageSource)
sourceHandler = new ImageLoaderSourceHandler();
else if (source is FileImageSource)
sourceHandler = new FileImageSourceHandler();
else if (source is StreamImageSource)
sourceHandler = new StreamImagesourceHandler();
else if (source is FontImageSource)
sourceHandler = new FontImageSourceHandler();
return sourceHandler;
}
}
}
将所有*.svg文件放在/Resources文件夹中的*.iOS文件夹中,仅此而已。
发布于 2020-10-15 05:58:09
我得到了同样的结果,这是我在标签栏中svg图像的解决方法。
对于android,请访问此页面https://shapeshifter.design/。
然后将您的SVG文件导入网站,然后下载xml文件,类似于以下操作(单击Import
,选择svg
,选择svg文件,然后选择Export
,向量可绘制,下载xml文件)。将xml文件复制到Android文件夹(请检查Resource/ Drawable
文件的)。注意:如果您想更改svg文件的行颜色,请打开xml,喜欢填充颜色,更改它。
然后,您可以像下面的代码一样在pcl中使用它。
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App3" xmlns:ffimageloadingsvg="clr-namespace:FFImageLoading.Svg.Forms;assembly=FFImageLoading.Svg.Forms"
BarBackgroundColor="Green"
x:Class="App3.MainPage">
<local:TodayPage IconImageSource="{x:OnPlatform Android=ic_today,iOS=today.svg}" >
</local:TodayPage>
<NavigationPage Title="Schedule" IconImageSource="myIcon.png">
<x:Arguments>
<local:Page1 />
</x:Arguments>
</NavigationPage>
</TabbedPage>
这是正在运行的截图。
对于IOS,请参考Dinesh_Official
在这个帖子中的回复:
https://forums.xamarin.com/discussion/179773/how-to-use-svg-image-for-tabbed-page-tabbar-icon
发布于 2020-10-15 05:59:19
对于调试SVGS,以下是一些可能有帮助的步骤。
public static void PrintEmbeddedResources()
{
#if DEBUG
var assembly = typeof(App).GetTypeInfo().Assembly;
var logTxt = "Embedded Resources:" + Environment.NewLine;
foreach (var res in assembly.GetManifestResourceNames())
{
Debug.WriteLine("found resource: " + res);
}
#endif
}
https://stackoverflow.com/questions/64361755
复制相似问题