如何覆盖Xamarin Android应用程序中的图标,使其在从一个选项卡页面返回到另一个选项卡页面时显示
我有在我的标签页上显示图标的代码。我的一个选项卡上有一个项目列表,当用户单击其中一个项目时,代码调用如何覆盖Xamarin Android应用程序中的图标,使其在从一个选项卡页面返回到另一个选项卡页面时显示,xamarin,icons,tabbedpage,Xamarin,Icons,Tabbedpage,我有在我的标签页上显示图标的代码。我的一个选项卡上有一个项目列表,当用户单击其中一个项目时,代码调用 navigation.PushAsync(new MyTabbedPage(data, template)); 将新的选项卡式页面推到原始页面上,只需一个选项卡,即可显示列表页面选项卡的图标。当用户完成对该图标的编辑后,他们要么单击完成并保存记录,要么单击Android后退按钮。那叫 await this.Navigation.PopAsync(); 返回到原始选项卡页 当选项卡只显示文本
navigation.PushAsync(new MyTabbedPage(data, template));
将新的选项卡式页面推到原始页面上,只需一个选项卡,即可显示列表页面选项卡的图标。当用户完成对该图标的编辑后,他们要么单击完成并保存记录,要么单击Android后退按钮。那叫
await this.Navigation.PopAsync();
返回到原始选项卡页
当选项卡只显示文本时,这种方式很好。当我使用TabbedRenderer显示图标而不是文本时,选项卡最初也会呈现良好效果,但当我从“详细信息”选项卡页面返回到原始选项卡页面时,它会呈现为没有图标。这是因为调用了my TabbedRenderer的DispatchDraw方法,但其上下文仍然是细节MyTabbedPage,而不是父级,只有一个选项卡。基本上,this.Context与this.Element不同步,因此我的代码无法检索选项卡以覆盖其图标。这是我的TabbedRenderer代码-此使用的imagePage.IConFile和imagePage.IconCode变量在初始化ContentPage(实现具有这些属性的ICustomIconPage接口)时在前面设置
在这个场景中,任何关于如何覆盖父选项卡页面中的图标而不是细节页面中的图标的帮助都将非常非常有用 当用户单击其中一项时,您真的需要推送到一个新的选项卡页面吗?您可以改用contentPage。不建议在一个项目中使用两个选项卡页。
using System;
using System.Linq;
using Android.App;
using Android.Content;
using Android.Views;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(MyTabbedPage), typeof(ExtendedTabbedPageRenderer))]
namespace MyRenderers
{
public static class DebugViewContents
{
public static void DebugLayout(this Android.Views.View self, int indent = 0)
{
// write info about me first
var indents = new string('\t', indent);
System.Diagnostics.Debug.WriteLine(indents + self.GetType().Name);
// check if I'm a view group
var vg = self as ViewGroup;
if (vg == null) return;
// enumerate my children
var children = Enumerable.Range(0, vg.ChildCount).Select(x => vg.GetChildAt(x));
// recurse on each child
foreach (var child in children)
DebugLayout(child, indent + 1);
}
}
public class ExtendedTabbedPageRenderer : TabbedRenderer
{
public ExtendedTabbedPageRenderer(Context context) : base(context) { }
protected override void DispatchDraw(global::Android.Graphics.Canvas canvas)
{
Activity activity = this.Context as Activity;
if (activity.ActionBar.TabCount > 0)
{
SetTabIcons();
}
base.DispatchDraw(canvas);
}
private void SetTabIcons()
{
var element = this.Element;
if (null == element)
{
return;
}
Activity activity = this.Context as Activity;
if ((null != activity && null != activity.ActionBar && activity.ActionBar.TabCount > 0))
{
for (int i = 0; i < element.Children.Count; i += 1)
{
Android.App.ActionBar.Tab tab = null;
try
{
tab = activity.ActionBar.GetTabAt(i);
}
catch
{
// If the tab does not exist for any reason, don't err - just don't try to replace the icon.
continue;
}
var page = element.Children[i];
if ((null != tab) && (null != page) && (null != page.IconImageSource))
{
if (tab.CustomView == null)
{
string iconKey = null;
string fontFileName = null;
var imagePage = page as ICustomIconPage;
// Show form-configured icon instead of text on the tab, if present
if (imagePage != null && imagePage.IconFontFile != null && imagePage.IconCode != null)
{
int fontSize = 30;
var drawable = new IconDrawable(this.Context, imagePage.IconCode, imagePage.IconFontFile).Color(Xamarin.Forms.Color.White.ToAndroid()).SizeDp(fontSize);
tab.SetIcon(drawable);
tab.SetText("");
}
}
}
}
}
}
}
}
public IconDrawable(Context context, string iconChar, string fontFaceFileName)
{
_iconChar = iconChar;
Init(context, fontFaceFileName);
}
private void Init(Context context, string fontFaceFileName)
{
_context = context;
_paint = new TextPaint
{
AntiAlias = true,
Color = Android.Graphics.Color.Black,
TextAlign = Paint.Align.Center,
UnderlineText = false
};
_paint.SetStyle(Paint.Style.Fill);
if (fontFaceFileName != null)
{
_paint.SetTypeface(Typeface.CreateFromAsset(context.Assets, $"{fontFaceFileName}"));
}
}