在Xamarin Forms中“重新添加” TabbedPage子级时,如何禁用BottomNavigationView转换模式?

时间:2018-12-29 05:33:43

标签: c# xamarin xamarin.forms xamarin.android

我有一个在BottomNavigationView侧使用Android的XF应用程序,该应用程序根据用户模式删除并添加了TabbedPage子级。以下是我的Android渲染器:

public class BottomTabPageRenderer : TabbedPageRenderer
{

    public BottomTabPageRenderer(Context context) : base(context) { }

    protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
    {
        base.OnElementChanged(e);

        if (ViewGroup != null && ViewGroup.ChildCount > 0)
        {
            BottomNavigationMenuView bottomNavigationMenuView = FindChildOfType<BottomNavigationMenuView>(ViewGroup);

            if (bottomNavigationMenuView != null)
            {
                var shiftMode = bottomNavigationMenuView.Class.GetDeclaredField("mShiftingMode");

                shiftMode.Accessible = true;
                shiftMode.SetBoolean(bottomNavigationMenuView, false);
                shiftMode.Accessible = false;
                shiftMode.Dispose();

                for (var i = 0; i < bottomNavigationMenuView.ChildCount; i++)
                {
                    var item = bottomNavigationMenuView.GetChildAt(i) as BottomNavigationItemView;
                    if (item == null) continue;

                    item.SetShiftingMode(false);
                    item.SetChecked(item.ItemData.IsChecked);
                }

                if (bottomNavigationMenuView.ChildCount > 0) bottomNavigationMenuView.UpdateMenuView();
            }

        }

        T FindChildOfType<T>(ViewGroup viewGroup) where T : Android.Views.View
        {
            if (viewGroup == null || viewGroup.ChildCount == 0) return null;

            for (var i = 0; i < viewGroup.ChildCount; i++)
            {
                var child = viewGroup.GetChildAt(i);

                var typedChild = child as T;
                if (typedChild != null) return typedChild;

                if (!(child is ViewGroup)) continue;

                var result = FindChildOfType<T>(child as ViewGroup);

                if (result != null) return result;
            }

            return null;
        }
   }
}

当用户通过单击按钮开始游戏时,底部的5个选项卡中的4个将被删除。当用户通过单击按钮再次结束游戏时,将再次添加选项卡。我尝试xxx.Children.Insert()将标签页放回原来的位置,但这给了我以下错误:

Java.Lang.IndexOutOfBoundsException: Index: 1, Size: 1

所以我最终得到了以下代码:

public static void ReAddChildren()
{
   mainPage.Children.Remove(gameTabPage);
   mainPage.Children.Add(homeTabPage);
   mainPage.Children.Add(helpTabPage);
   mainPage.Children.Add(settingsTabPage);
   mainPage.Children.Add(dictTabPage);
   mainPage.Children.Add(gameTabPage);
 }

这有效,但是现在shiftingMode又回来了。任何人都知道,当我“重新添加”选项卡项时如何禁用此功能?

3 个答案:

答案 0 :(得分:0)

Android仅在28.0.0支持库上对其进行了更新。 不知道Xamarin是否可以访问此本机方法setLabelVisibilityMode()以禁用移位。

navBottom.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED);

答案 1 :(得分:0)

在渲染器中,您可以轻松地使用Xamarin.Forms中的此扩展方法来管理移位模式。

https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.Android/Renderers/BottomNavigationViewUtils.cs

所以您会得到:

using static Xamarin.Forms.Platform.Android.BottomNavigationViewUtils;
public class BottomTabPageRenderer : TabbedPageRenderer
{

    public BottomTabPageRenderer(Context context) : base(context) { }

    protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
    {
        base.OnElementChanged(e);

        if (ViewGroup != null && ViewGroup.ChildCount > 0)
        {
            BottomNavigationMenuView bottomNavigationMenuView = FindChildOfType<BottomNavigationMenuView>(ViewGroup);

            if (bottomNavigationMenuView != null)
            {
                // use extension method from XF
                bottomNavigationMenuView.SetShiftMode(false, false);
            }

        }

        T FindChildOfType<T>(ViewGroup viewGroup) where T : Android.Views.View
        {
            if (viewGroup == null || viewGroup.ChildCount == 0) return null;

            for (var i = 0; i < viewGroup.ChildCount; i++)
            {
                var child = viewGroup.GetChildAt(i);

                var typedChild = child as T;
                if (typedChild != null) return typedChild;

                if (!(child is ViewGroup)) continue;

                var result = FindChildOfType<T>(child as ViewGroup);

                if (result != null) return result;
            }

            return null;
        }
   }
}

答案 2 :(得分:0)

正如Pawel所述,您可以轻松地使用Xamarin.Forms的扩展方法来管理班次模式。但这是对我有用的

 public class CustomTabbedPageRenderer : TabbedPageRenderer
{

    public CustomTabbedPageRenderer(Context context) : base(context)
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
    {
        base.OnElementChanged(e);

        if (ViewGroup != null && ViewGroup.ChildCount > 0)
        {
            BottomNavigationView bottomNavigationView = FindChildOfType<BottomNavigationView>(ViewGroup);

            if (bottomNavigationView != null)
            {
                // use extension method from XF
                bottomNavigationView.SetShiftMode(false, false);
            }

        }
    }

    private T FindChildOfType<T>(ViewGroup viewGroup) where T : Android.Views.View
    {
        if (viewGroup == null || viewGroup.ChildCount == 0) return null;

        for (var i = 0; i < viewGroup.ChildCount; i++)
        {
            var child = viewGroup.GetChildAt(i);

            var typedChild = child as T;
            if (typedChild != null) return typedChild;

            if (!(child is ViewGroup)) continue;

            var result = FindChildOfType<T>(child as ViewGroup);

            if (result != null) return result;
        }

        return null;
    }

    protected override void DispatchDraw(Canvas canvas)
    {
        base.DispatchDraw(canvas);
    }


}