Xamarim.Forms TabbedPage uses the bottom Tab page in Android to improve the display function

Posted by CONTEMAN on Sun, 10 Nov 2019 23:07:25 +0100

The TabbedPage of Xamarin.Forms has been added to the Android system. The properties of the Tab option are displayed at the bottom,

Just reference the Android namespace in TabbedPage and add the attributes shown at the bottom.

xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
 android:TabbedPage.ToolbarPlacement="Bottom"

The default tabbed page in iOS is displayed at the bottom without special processing.

But in Android, when there are more than four tabs, tabbed page will enter a state called shift mode, and only the icon and the text of the currently active Tab page will be displayed.

As shown in the figure below.

If you do not set the Tab page icon, you will find that the inactive Tab page is not visible.

 

The default mode is obviously not in line with daily use habits, which is also mentioned in the official issue, but there is no update.

If you want to avoid this display effect now, you need to use CustomeRenderer to avoid this problem.

First, in the shared project, create a new class named BottomTabPage and inherit TabbedPage.

 

iOS project does not need to be processed. Android project needs to implement Renderer. At present, my implementation code is as follows:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using Android.Content;
 5 using Android.Support.Design.Widget;
 6 using Android.Views;
 7 using LearningProject.Control;
 8 using LearningProject.Droid.Renderers;
 9 using Xamarin.Forms;
10 using Xamarin.Forms.Platform.Android;
11 using Xamarin.Forms.Platform.Android.AppCompat;
12 using View = Android.Views.View;
13 
14 [assembly: ExportRenderer(typeof(BottomTabPage), typeof(BottomTabPageRenderer))]
15 namespace Test.Droid.Renderers
16 {
17     public class BottomTabPageRenderer : TabbedPageRenderer
18     {
19         private bool _isShiftModeSet;
20         public BottomTabPageRenderer(Context context) : base(context)
21         {
22         }
23 
24         protected override void OnLayout(bool changed, int l, int t, int r, int b)
25         {
26             base.OnLayout(changed, l, t, r, b);
27             try
28             {
29                 if (!_isShiftModeSet)
30                 {
31                     var children = GetAllChildViews(ViewGroup);
32 
33                     if (children.SingleOrDefault(x => x is BottomNavigationView) is BottomNavigationView bottomNav)
34                     {
35                         bottomNav.SetShiftMode(false, false);
36                         _isShiftModeSet = true;
37                     }
38                 }
39             }
40             catch (Exception e)
41             {
42                 Console.WriteLine($"Error setting ShiftMode: {e}");
43             }
44         }
45         private List<View> GetAllChildViews(View view)
46         {
47             if (!(view is ViewGroup group))
48             {
49                 return new List<View> { view };
50             }
51 
52             var result = new List<View>();
53 
54             for (int i = 0; i < group.ChildCount; i++)
55             {
56                 var child = group.GetChildAt(i);
57 
58                 var childList = new List<View> { child };
59                 childList.AddRange(GetAllChildViews(child));
60 
61                 result.AddRange(childList);
62             }
63 
64             return result.Distinct().ToList();
65         }
66     }
67 }

 

Then change the reference of TabbedPage in the page to the BottomTabPage control in the shared project.

<controls:BottomTabPage x:Class="Test.Views.MainView"
                        xmlns="http://xamarin.com/schemas/2014/forms"
                        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                        xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
                        xmlns:controls="clr-namespace:Test.Control"
                        xmlns:iOS="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
                        xmlns:views="clr-namespace:Test.Views"
                        android:TabbedPage.ToolbarPlacement="Bottom"
                        iOS:Page.UseSafeArea="true">
</controls:BottomTabPage>

The display effect is as shown in the following figure.

Topics: Android iOS