微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在Xamarin Android应用程序中覆盖图标,以便在从一个TabbedPage返回到另一个TabbedPage时显示它们

如何解决如何在Xamarin Android应用程序中覆盖图标,以便在从一个TabbedPage返回到另一个TabbedPage时显示它们

我有一些代码在TabbedPage上显示FontAwesome图标。我的一个标签上有一个项目列表,当用户单击其中一个项目时,代码调用

navigation.PushAsync(new MyTabbedPage(data,template)); 

将新的选项卡式页面推到原始页面上,只有一个选项卡,显示列表页面选项卡的图标。用户完成该图标的编辑后,他们要么单击“完成”并保存记录,要么单击“ Android后退”按钮。那叫

await this.Navigation.PopAsync();

返回到原始的TabbedPage。

这工作正常时,标签显示文本。当我使用TabbedRenderer显示图标而不是文本时,这些选项卡最初也可以很好地呈现,但是当我将详细信息TabbedPage返回到原始选项卡时,它将不显示任何图标。那是因为我的TabbedRenderer的dispatchDraw方法调用了,但是它的Context仍然是MyTabbedPage的详细信息,而不是父项,只有一个选项卡。基本上,this.Context与this.Element不同步,因此我的代码无法检索选项卡以覆盖其图标。这是我的TabbedRenderer代码-对其ContentPage进行初始化(实现具有这些属性的ICustomIconPage接口)后,便会更早设置使用的imagePage.IconFontFile和imagePage.IconCode变量。

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("");
                            }
                        }

                    }
                }
            }
        }
    }


}

上面的代码使用here中的IconDrawable类。我对该类如何加载Typeface做了一些小调整-这是我对两个更改的方法的版本:

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}"));
    }
}

在这种情况下,任何帮助找出如何覆盖父选项卡式页面中的图标(而不是详细信息)的帮助都将非常非常有帮助!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。