【发布时间】:2021-12-30 14:18:53
【问题描述】:
我正在处理 Xamarin 中的 TabbedPage。但是有一个问题是:如何在选择 Tab 时仅部分更改图标颜色。这是我想要的例子:
在 Xamarin 中,它具有更改部分图像颜色的解决方案。还是在选择选项卡时更改图标。这是我处理的代码
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
BackgroundColor="#fff"
....>
<views:Page1 Title="Page 1" IconImageSource="homeicon" BackgroundColor="#fff"/>
<views:Page2 Title="Page 2" IconImageSource="feeds" BackgroundColor="#fff"/>
<views:Page3 Title="Page 3" IconImageSource="chats" BackgroundColor="#fff" />
<views:Page4 Title="Page 4" IconImageSource="usericon" BackgroundColor="#fff"/>
</TabbedPage>
MyTabbedPageRenderer iOS
public class MyTabbedPageRenderer : TabbedRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
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++)
{
UpdateTabBarItem(TabBar.Items[i]);
}
}
}
private void UpdateTabBarItem(UITabBarItem item)
{
if (item == null) return;
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
{
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;
}
}
AppDelegate.cs
UITabBar.Appearance.BackgroundImage = new UIImage();
UITabBar.Appearance.ShadowImage = new UIImage();
UITabBar.Appearance.SelectedImageTintColor = UIColor.FromRGB(0, 170, 19);
它显示的结果:
如何在 android 和 iOS 中选择 Tab 时仅部分更改图标颜色。请求帮忙。谢谢
更新
我根据您的示例进行了更新,但它似乎仍然不起作用。我创建了一个新项目
MainView.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:views="clr-namespace:Appssss.Views"
x:Class="Appssss.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" />
<views:Page5 Title="Page 5" IconImageSource="usericon" BackgroundColor="#fff"/>
</TabbedPage>
MainView.xaml.cs
namespace Appssss.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Mainview : Xamarin.Forms.TabbedPage
{
public Mainview(int index)
{
InitializeComponent();
On<Xamarin.Forms.PlatformConfiguration.Android>().SetToolbarPlacement(ToolbarPlacement.Bottom);
SetPage(index);
}
void SetPage(int index)
{
CurrentPage = Children[index];
}
}
}
CustomTabbedPageRenderer.cs
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Appssss.Droid.Renderers;
using Google.Android.Material.Tabs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android.AppCompat;
using static Google.Android.Material.Tabs.TabLayout;
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedPageRenderer))]
namespace Appssss.Droid.Renderers
{
public class CustomTabbedPageRenderer : TabbedPageRenderer, IOnTabSelectedListener
{
public CustomTabbedPageRenderer(Context context) : base(context)
{
}
void IOnTabSelectedListener.OnTabSelected(TabLayout.Tab tab)
{
if (tab == null)
{
return;
}
switch (tab.Text)
{
case "Page 1":
tab.SetIcon(Resource.Drawable.homeiconselect);
break;
case "Page 2":
tab.SetIcon(Resource.Drawable.feedsselect);
break;
case "Page 3":
tab.SetIcon(Resource.Drawable.moneysselect);
break;
case "Page 4":
tab.SetIcon(Resource.Drawable.chatsselect);
break;
case "Page 5":
tab.SetIcon(Resource.Drawable.usericonselect);
break;
default:
break;
}
}
void IOnTabSelectedListener.OnTabUnselected(TabLayout.Tab tab)
{
if (tab == null)
{
return;
}
switch (tab.Text)
{
case "Page 1":
tab.SetIcon(Resource.Drawable.homeicon);
break;
case "Page 2":
tab.SetIcon(Resource.Drawable.feeds);
break;
case "Page 3":
tab.SetIcon(Resource.Drawable.moneys);
break;
case "Page 4":
tab.SetIcon(Resource.Drawable.chats);
break;
case "Page 5":
tab.SetIcon(Resource.Drawable.usericon);
break;
default:
break;
}
}
}
}
这是结果,我注意到它仍然没有按预期改变:
我创建了不同的图标,但注意到它仍然无法正常工作。我还没有在 iOS 上尝试过。
更新 2
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Appssss.Droid.Renderers;
using Google.Android.Material.BottomNavigation;
using Google.Android.Material.Tabs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms.Platform.Android.AppCompat;
using static Google.Android.Material.BottomNavigation.BottomNavigationView;
using static Google.Android.Material.Tabs.TabLayout;
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedPageRenderer))]
namespace Appssss.Droid.Renderers
{
public class CustomTabbedPageRenderer : TabbedPageRenderer, IOnTabSelectedListener
{
public CustomTabbedPageRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
IEnumerable<View> children = GetAllChildViews(ViewGroup);
BottomNavigationView bottomNavBar = (BottomNavigationView)children.SingleOrDefault(view => view is BottomNavigationView);
if (bottomNavBar != null)
{
bottomNavBar.NavigationItemSelected += BottomNavBar_NavigationItemSelected;
bottomNavBar.Menu.GetItem(0).SetIcon(Resource.Drawable.diamond);
}
}
}
int previous;
private void BottomNavBar_NavigationItemSelected(object sender, NavigationItemSelectedEventArgs e)
{
var current = e.Item.ItemId;
switch (e.Item.ToString())
{
case "Page 1":
e.Item.SetIcon(Resource.Drawable.diamond);
break;
case "Page 2":
e.Item.SetIcon(Resource.Drawable.diamond);
break;
default:
break;
}
var previousView = sender as BottomNavigationView;
IMenu menu = previousView.Menu;
var previousItem = menu.GetItem(previous);
if (previousItem.IsChecked)
{
switch (previousItem.ToString())
{
case "Page 1":
previousItem.SetIcon(Resource.Drawable.cactus_24px);
break;
case "Page 2":
previousItem.SetIcon(Resource.Drawable.cactus_24px);
break;
default:
break;
}
}
previous = current;
}
private IEnumerable<View> GetAllChildViews(View view)
{
if (!(view is ViewGroup group))
return new List<View> { view };
List<View> result = new List<View>();
int childCount = group.ChildCount;
for (int i = 0; i < childCount; i++)
{
View child = group.GetChildAt(i);
List<View> childList = new List<View> { child };
childList.AddRange(GetAllChildViews(child));
result.AddRange(childList);
}
return result.Distinct();
}
}
}
得到错误:
我试过了
更新3
好像没有使用库:using static Google.Android.Material.BottomNavigation.BottomNavigationView;
【问题讨论】:
标签: xamarin