Can one use system icons on tabs in Xamarin Forms?

后端 未结 3 1965
遇见更好的自我
遇见更好的自我 2021-01-11 09:13

Is there a way to specify a \"system\" icon to be displayed on a tab when using Xamarin Forms? I would like to use icons such as Favourites, Bookmark, History etc but I do n

相关标签:
3条回答
  • 2021-01-11 10:04

    You should write custom TabbedPage renderer for iOS project:

    public class YourTabbedRenderer : TabbedRenderer {
            public override void ViewWillAppear(bool animated)
            {
                base.ViewWillAppear(animated);
                var items = TabBar.Items;
    
                for (var i = 0; i < items.Length; i++) {
                    // set your icons here, you could do some string comparison (check tab title or tab icon resource name)
                    // items[i].Image = 
                    // items[i].SelectedImage = 
                }
            }
        }
    

    http://developer.xamarin.com/guides/cross-platform/xamarin-forms/custom-renderer/

    0 讨论(0)
  • 2021-01-11 10:11

    In order to use icons, you need a platform-specific structure. In Xamarin.Forms, for this to work:

    Icon = "youricon.png";
    

    You need:

    • iOS: put the image in /Resources/youricon.png
    • Android: put the image in /Resources/drawable/youricon.png
    • Win Phone: put the image in the Windows Phone application project root.
    0 讨论(0)
  • 2021-01-11 10:14

    For iOS

    you need a custom renderer for your page. In my example, it is CustomTabsPage class. You cannot just use system icons to create a UIImage. We need to use UITabBarItem. The problem is that UITabBarItem doesn't allow changes to either title or image/icon. But, we can copy an image from it.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using UIKit;
    using ButtonRendererDemo;
    using ButtonRendererDemo.iOS;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.iOS;
    
    [assembly: ExportRenderer(typeof(CustomTabsPage), typeof(CustomTabsPageRenderer))]
    namespace ButtonRendererDemo.iOS
    {
        public class CustomTabsPageRenderer : TabbedRenderer
        {
    
             #region Sytem Image with custom title
    
            public override void ViewWillAppear(bool animated)
            {
                base.ViewWillAppear(animated);
    
                foreach (var item in TabBar.Items)
                {
                    item.Image = GetTabIcon(item.Title);
                }
            }
    
            private UIImage GetTabIcon(string title)
            {
                UITabBarItem item = null;
    
                switch (title)
                {
                    case "Profile":
                        item = new UITabBarItem(UITabBarSystemItem.Search, 0);
                        break;
                    case "Settings":
                        item = new UITabBarItem(UITabBarSystemItem.Bookmarks, 0);
                        break;
                }
    
                var img = (item != null) ? UIImage.FromImage(item.SelectedImage.CGImage, item.SelectedImage.CurrentScale, item.SelectedImage.Orientation) : new UIImage();
                return img;
            }
    
            #endregion
        }
    }
    

    For Android

    things are easier

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    using ButtonRendererDemo;
    using ButtonRendererDemo.Droid;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.Android;
    using Xamarin.Forms.Platform.Android.AppCompat;
    using Android.Support.Design.Widget;
    
    [assembly: ExportRenderer(typeof(CustomTabsPage), typeof(CustomTabsPageRenderer))]
    namespace ButtonRendererDemo.Droid
    {
        public class CustomTabsPageRenderer : TabbedPageRenderer
        {
            protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
            {
                base.OnElementChanged(e);
    
                //var layout = (TabLayout)ViewGroup.GetChildAt(1); //should be enough but just for robustness we use loop below
    
                TabLayout layout = null;
                for (int i = 0; i < ChildCount; i++)
                {
                    layout = GetChildAt(i) as TabLayout;
                    if (layout != null)
                        break;
                }
                if (layout != null)
                {
                    for (int tabIndex = 0; tabIndex < layout.TabCount; tabIndex++)
                        SetTabIcon(layout, tabIndex);
                }
            }
    
            private void SetTabIcon(TabLayout layout, int tabIndex)
            {
                var tab = layout.GetTabAt(tabIndex);
    
                switch (tabIndex)
                {
                    case 0:
                        tab.SetIcon(Resource.Drawable.icon2);//from local resource
                        break;
                    case 1:
                        tab.SetIcon(Resource.Drawable.ic_media_play_dark);//from Android system, depends on version !
                        break;
                }
            }
        }
    
    }
    

    0 讨论(0)
提交回复
热议问题