如何在Android中重新选择选项卡时更改TabbedPage图标?

Sam*_*tar 8 c# xamarin xamarin.forms

我有一个应用程序使用Xamarin Forms TabbedPage它有一个功能,允许用户暂停和播放页面.请参阅下面的代码.

共享代码

public partial class MainPage : TabbedPage
{
   public MainPage()
   {
      InitializeComponent();

      var homePage = new NavigationPage(new HomePage())
      { 
         Title = "Home",
         Icon = "ionicons_2_0_1_home_outline_25.png"
      };

      var phrasesPage = new NavigationPage(new PhrasesPage())
      {
         Title = "Play",
         Icon = "ionicons_2_0_1_play_outline_25.png"
       };

       Children.Add(homePage);
       Children.Add(phrasesPage);
   }
}
Run Code Online (Sandbox Code Playgroud)

在iOS渲染器中:

public class TabbedPageRenderer : TabbedRenderer
{
   private MainPage _page;
   protected override void OnElementChanged(VisualElementChangedEventArgs e)
  {
      base.OnElementChanged(e);
      var tabbarController = (UITabBarController)this.ViewController;
      if (null != tabbarController)
      {
         tabbarController.ViewControllerSelected += OnTabBarReselected;
       }
   }

   void OnTabBarReselected(object sender, UITabBarSelectionEventArgs e)
   {
      var tabs = Element as TabbedPage;
      var playTab = tabs.Children[4];

      if (TabBar.SelectedItem.Title == "Play") {
         if (tabs != null)
         {
            playTab.Title = "Pause";
            playTab.Icon = "ionicons_2_0_1_pause_outline_22.png";
         }
         App.pauseCard = false;
       }
       else {
        if (tabs != null) {
           playTab.Title = "Play";
           playTab.Icon = "ionicons_2_0_1_play_outline_25.png";
       }
       App.pauseCard = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

Android渲染器

public class MyTabbedPageRenderer: TabbedPageRenderer, TabLayout.IOnTabSelectedListener
{
    if (e.PropertyName == "Renderer")
    {
       viewPager = (ViewPager)ViewGroup.GetChildAt(0);
       tabLayout = (TabLayout)ViewGroup.GetChildAt(1);
       setup = true;

       ColorStateList colors = null;
       if ((int)Build.VERSION.SdkInt >= 23)
       {
           colors = Resources.GetColorStateList(Resource.Color.icon_tab, Forms.Context.Theme);
       }
       else
       {
           colors = Resources.GetColorStateList(Resource.Color.icon_tab);
       }

       for (int i = 0; i < tabLayout.TabCount; i++)
       {
           var tab = tabLayout.GetTabAt(i);
           var icon = tab.Icon;
           if (icon != null)
           {
               icon = Android.Support.V4.Graphics.Drawable.DrawableCompat.Wrap(icon);
               Android.Support.V4.Graphics.Drawable.DrawableCompat.SetTintList(icon, colors);
           }
       }
   }

   void TabLayout.IOnTabSelectedListener.OnTabReselected(TabLayout.Tab tab)
   {
      var tabs = Element as TabbedPage;
      var playTab = tabs.Children[4];
      var selectedPosition = tab.Position;

      if(selectedPosition == 4) 
      {
         if (playTab.Title == "Play")
         {
            if (tabs != null)
            {
               playTab.Title = "Pause";
               playTab.Icon = "ionicons_2_0_1_pause_outline_22.png";
            }
            App.pauseCard = false;
          }
          else
          {
             if (tabs != null)
             {
                playTab.Title = "Play";
                playTab.Icon = "ionicons_2_0_1_play_outline_25.png";
             }
             App.pauseCard = true;
           }
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

这完全有效iOS.但不知何故Android只会Title改变而不是改变Icon.任何人都知道我错过了什么或应该怎么做?此外,这可以在共享代码中完成,而不是在每个平台的代码上重复几乎完全相同的行吗?

Col*_*SFT 5

Custom Renderer不需要,您可以直接在共享代码中更改TitleIcon

只是在实现CurrentPageChanged事件TabbedPage

完整的代码

public partial class TabbedPage1 : TabbedPage
{
    NavigationPage homePage;
    NavigationPage phrasesPage;

    public TabbedPage1 ()
    {
        InitializeComponent();

        var homePage = new NavigationPage(new Page1())
        {
            Title = "Home",
            Icon = "1.png"
        };

        var phrasesPage = new NavigationPage (new Page2())
        {
            Title = "Play",
            Icon = "1.png"
        };

        Children.Add(homePage);
        Children.Add(phrasesPage);

        this.CurrentPageChanged += (object sender, EventArgs e) => {

            var i = this.Children.IndexOf(this.CurrentPage);

            if (i == 0)
            {
                homePage.Title = "HomeChanged";
                homePage.Icon = "2.png";
            }
            else {
                phrasesPage.Title = "PlayChanged";
                phrasesPage.Icon = "2.png";
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

结果

在此处输入图片说明

PS:使图像文件可从其他平台访问。

iOS- Resources

Android- Resources->drawable


pin*_*dax 5

OnTabReselected您可以通过使用在 .txt 文件中的参数中传递给您的选项卡来完成此操作TabRenderer

您可以使用此对象移动整个逻辑。

这是我的整个渲染器文件(Android):

[assembly: ExportRenderer(typeof(SWTabSelection.MainPage), typeof(SWTabSelection.Droid.MyTabbedPageRenderer))]
namespace SWTabSelection.Droid
{
    public class MyTabbedPageRenderer : TabbedPageRenderer, TabLayout.IOnTabSelectedListener
    {
        private ViewPager viewPager;
        private TabLayout tabLayout;
        private bool setup;

        public MyTabbedPageRenderer() { }

        public MyTabbedPageRenderer(Context context) : base(context)
        {
            //Use this constructor for newest versions of XF saving the context parameter 
            // in a field so it can be used later replacing the Xamarin.Forms.Forms.Context which is deprecated.
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if (e.PropertyName == "Renderer")
            {
                viewPager = (ViewPager)ViewGroup.GetChildAt(0);
                tabLayout = (TabLayout)ViewGroup.GetChildAt(1);
                setup = true;

                ColorStateList colors = GetTabColor();

                for (int i = 0; i < tabLayout.TabCount; i++)
                {
                    var tab = tabLayout.GetTabAt(i);

                    SetTintColor(tab, colors);
                }
            }
        }


    void TabLayout.IOnTabSelectedListener.OnTabReselected(TabLayout.Tab tab)
    {
        // To have the logic only on he tab on position 1
        if(tab == null || tab.Position != 1)
        {
            return;
        }

        if(tab.Text == "Play")
        {
            tab.SetText("Pause");
            tab.SetIcon(Resource.Drawable.ionicons_2_0_1_pause_outline_25);
            App.pauseCard = false;
        }
        else
        {
            tab.SetText("Play");
            tab.SetIcon(Resource.Drawable.ionicons_2_0_1_play_outline_25);
            App.pauseCard = true;
        }

        SetTintColor(tab, GetTabColor());

    }

        void SetTintColor(TabLayout.Tab tab, ColorStateList colors)
        {
            var icon = tab?.Icon;
            if(icon != null)
            {
                icon = Android.Support.V4.Graphics.Drawable.DrawableCompat.Wrap(icon);
                Android.Support.V4.Graphics.Drawable.DrawableCompat.SetTintList(icon, colors);            
            }
        }

        ColorStateList GetTabColor()
        {
            return ((int)Build.VERSION.SdkInt >= 23) 
                ? Resources.GetColorStateList(Resource.Color.icon_tab, Forms.Context.Theme)
                               : Resources.GetColorStateList(Resource.Color.icon_tab);
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

我在上面的代码中遇到的唯一问题是图标没有采用色调颜色,因此创建了一个具有与设置色调相同逻辑的函数,并且我在选项卡重新选择上使用它。如果您的应用程序中只有一个选项卡,您可以在 Android 主题/样式 xml 中设置全局色调。

希望这可以帮助。