我正在處理 Xamarin 中的 TabbedPage。但是有一個問題是:如何在選擇 Tab 時僅部分更改圖示顏色。這是我想要的例子:

在 Xamarin 中,它有一個解決方案來更改部分影像顏色。或者是在選擇 Tab 時更改圖示。這是我處理的代碼
<?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 時,如何僅部分更改圖示顏色。請求幫忙。謝謝
更新
我根據您的示例進行了更新,但似乎仍然無法正常作業。我創建了一個新專案
主視圖.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>
主視圖.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;
uj5u.com熱心網友回復:
一種簡單的方法是在選擇選項卡時更改圖示。使用兩個圖示,一個黑色,一個紅色。
通常,如果我們想更改圖示顏色,一種方法是像您發布的結果(第二個螢屏截圖)一樣設定背景。第二種方法是使用材質圖示而不是影像源。
但是所有方法都不會將顏色更改為紅色并留下兩條黑線作為您想要的示例。
一個復雜的方法是在選擇 Tab 時繪制一個新影像。Xamarin.Forms 提供了幾種方法來做到這一點:
- Skiasharp:https ://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/
- 形狀:https : //docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/shapes/path
更新:
您可以在自定義渲染器中執行此操作。
Android: Android 提供了一個類IOnTabSelectedListener來監聽選項卡的選中和未選中狀態。下面是一個簡單的代碼供您參考。
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedPageRenderer))]
namespace App18.Droid
{
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.icon);
break;
case "Page 2":
tab.SetIcon(Resource.Drawable.icon);
break;
default:
break;
}
}
void IOnTabSelectedListener.OnTabUnselected(TabLayout.Tab tab)
{
if (tab == null)
{
return;
}
switch (tab.Text)
{
case "Page 1":
tab.SetIcon(Resource.Drawable.cactus_24px);
break;
case "Page 2":
tab.SetIcon(Resource.Drawable.cactus_24px);
break;
default:
break;
}
}
}
}
iOS:對于 ios,您可以使用 ViewControllerSelected 來注冊方法ViewControllerSelected。有關更多詳細資訊,請查看以下鏈接。單擊同一選項卡文本/圖示兩次時,如何使選項卡式頁面導航?
更新2:
Android:對于底部的選項卡,您需要訪問本機BottomNavigationView.
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedPageRenderer))]
namespace App18.Droid
{
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:
對于View的錯誤,使用Android.Views.View代替Xamarin.Forms.View。
using View = Android.Views.View;
對于專案的錯誤,我添加了所有帶有您使用的參考的代碼,專案沒有錯誤。清理 bin 和 obj 檔案夾以再次重建專案。
更新4:
TabbedPage在任何函式之外宣告一個實體變數。并在bottomNavBar不為空時設定該值。
TabbedPage tabbedPage;
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Xamarin.Forms.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)
{
tabbedPage = e.NewElement;
bottomNavBar.NavigationItemSelected = BottomNavBar_NavigationItemSelected;
bottomNavBar.Menu.GetItem(0).SetIcon(Resource.Drawable.diamond_24);
}
}
}
設定CurrentPage的tabbedPage在BottomNavBar_NavigationItemSelected。
private void BottomNavBar_NavigationItemSelected(object sender, BottomNavigationView.NavigationItemSelectedEventArgs e)
{
var current = e.Item.ItemId;
switch (e.Item.ToString())
{
case "Page 1":
e.Item.SetIcon(Resource.Drawable.diamond_24);
break;
case "Page 2":
e.Item.SetIcon(Resource.Drawable.diamond_24);
break;
case "Page 3":
e.Item.SetIcon(Resource.Drawable.diamond_24);
break;
default:
break;
}
var previousView = sender as BottomNavigationView;
IMenu menu = previousView.Menu;
var previousItem = menu.GetItem(previous);
if (previous != current)
{
if (previousItem.IsChecked)
{
switch (previousItem.ToString())
{
case "Page 1":
previousItem.SetIcon(Resource.Drawable.cactus_24);
break;
case "Page 2":
previousItem.SetIcon(Resource.Drawable.cactus_24);
break;
case "Page 3":
previousItem.SetIcon(Resource.Drawable.cactus_24);
break;
default:
break;
}
}
}
tabbedPage.CurrentPage = tabbedPage.Children[current];
previous = current;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/397992.html
標籤:沙马林
