如何在Xamarin中将svg图像加载到选项卡标题中

如何在Xamarin中将svg图像加载到选项卡标题中,svg,xamarin.forms,tabs,Svg,Xamarin.forms,Tabs,我正在构建一个简单的应用程序,它有3个选项卡,每个选项卡都有一个图标和一个文本。 我基于代码的示例项目存在于此处: 我发现的唯一问题是,它使用像素化图像作为选项卡标题,我想将其更改为SVG资源文件 我添加了一个FFImageLoading库,并从这里添加了svg支持 我设法将一个图像添加到其中一个选项卡内容页,但在标题中没有看到我试图看到的svg图像 这是我目前的代码: TodayPage.xaml.cs public partial class TodayPage : ContentPag

我正在构建一个简单的应用程序,它有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";
        }
    }
public分部类今日页面:ContentPage
{
今日公共网页()
{
初始化组件();
初始化组件();

//IconImageSource=“today.png”我得到了相同的结果,下面是我在选项卡栏中针对svg图像的解决方法

对于android,请访问此页面

然后将SVG文件导入网站,然后下载xml文件,如以下操作(单击
import
,选择
SVG
,选择SVG文件,然后选择
Export
,将可绘制文件矢量化,下载xml文件)。将xml文件复制到Android
Resource/drawable
文件夹(请检查生成操作是否为xml文件的
AndroidResource
)。注意:如果要更改svg文件的线条颜色,请打开xml,然后更改填充颜色

然后可以在PCLXML中使用它,如下面的代码所示

<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_官方的回复:


对于调试SVG,以下是一些可能有帮助的步骤

  • 如果您更换了另一个已确认的工作SVG,它会工作吗?如果不是,则ffimageloading会初始化吗

  • 确认嵌入的资源。(将其放入App.xaml.cs中)

  • 验证您的svg是否已优化。以下是您推荐的工具:

  • ffimageloading有时与特定SVG存在问题。 检查他们的github上的问题,看看是否有其他人报告了类似于您的问题,并希望发布一个解决方案


  • today.svg是作为嵌入式资源添加的,对吗?(很抱歉,这个问题很明显,只是检查一下)1.我不确定它们是否优化了,我从这里下载了一个2.资源是嵌入式资源,我可以在调试中看到它以正确的名称进入循环。3.我使用了CachedImageRenderer.Init(true);var ignore=typeof(SvgCachedImage);就像在FfimageLoading的wiki中一样,android解决方案对我很有效,我仍然不知道如何实现iOS变体,以及在加载不同的资源/渲染器时如何区分android和iOS。Lean Lu,我是否需要为我将拥有的每个选项卡创建选项卡渲染器?@Dermemo在iOS中,你应该创建一个custom呈现程序,然后覆盖
    GetIcon
    方法,这是演示代码。您也可以下载。我更新了我的问题,似乎从来没有调用过GetIcon。我在原始帖子中附加了我的新代码。我感谢您的帮助!
    <?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>
    
    [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;
            }
          
            
            
        }
        
    }
    
    <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> 
    
        <?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>
    
    [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;
            }
          
            
            
        }
        
    }
    
    <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>
    
        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
        }