I've encountered a problem working with Xamarin Forms for Android. I've created a TabbedPage
with ContentPages for displaying different content. At the bottom, there is a navigational tab bar, which should have icons displayed. What is the way to center the tab bar icons or align the displayed content, so that the icon would be in the center? Currently, the text is below the horizontal centerline of the individual tab bar item while the icon is above it:
This project is for Android only
<?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:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
x:Class="RandomMovie.MainPage"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
xmlns:flv="clr-namespace:DLToolkit.Forms.Controls;assembly=DLToolkit.Forms.Controls.FlowListView"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:windows="clr-namespace:Xamarin.Forms.PlatformConfiguration.WindowsSpecific;assembly=Xamarin.Forms.Core">
<ContentPage Padding="0,-15,0,0" IconImageSource="@drawable/search_icon.png">
<CollectionView ItemsSource="{Binding Watchlist}" Margin="0" >
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Margin="0" Padding="5,5,5,0">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Image Margin="0"
HeightRequest="300"
WidthRequest="170" Aspect="AspectFit"
VerticalOptions="End">
<Image.Source >
<UriImageSource
Uri="{Binding poster_path}"
CacheValidity="14"
CachingEnabled="true"
>
</UriImageSource>
</Image.Source>
</Image>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
<ContentPage Title="Search">
<ScrollView>
<ListView x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollView>
</ContentPage>
<ContentPage Title="Ratings">
</ContentPage>
There is no way to this from XAML code only.
To achieve this on Android you need to get access to the native BottomNavigationView and change LabelVisibilityMode
to LabelVisibilityMode.LabelVisibilityUnlabeled
Here's how I did in one of my apps using a custom renderer for TabbedPage
:
using System.Collections.Generic;
using System.Linq;
using Android.Content;
using Android.Views;
using SampleApp.Droid.Renderers;
using Google.Android.Material.BottomNavigation;
using Plugin.Badge.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using static Google.Android.Material.BottomNavigation.BottomNavigationView;
using View = Android.Views.View;
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedPageRenderer))]
namespace SampleApp.Droid.Renderers
{
public class CustomTabbedPageRenderer : TabbedPageRenderer
{
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.LabelVisibilityMode = LabelVisibilityMode.LabelVisibilityUnlabeled;
}
}
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();
}
}
}