In my cross-platform Xamarin Forms app, specifically on Android, I want to be able to customize the appearance of the items in the navigation bar of the
Xamarin.Forms.TabbedPage
. In particular, I want to be able to change the background for focused items in the bar from a solid light grey cropped circle (see image below) to a different shape, for example a green rectangular frame (the actual shape is not important).
I know how to change the background for an item depending on state, my problem is I cannot find which style or similar I need to modify to change the background for the navigation items in
TabbedPage
.
Typically for the Android app project of a Xamarin Forms app, the
Tabbar.axml
file is contained in the
Resources/Layout
folder, but any change I make in this file does not seem to apply to the appearance of the navigation tab. For example, I tried to add the following line:
app:tabBackground="@drawable/background_states"
but I could not see any indication that my change was applied.
I have also tried identifying more generally which Android style to override, but to no avail.
Can anybody give me a push in the right direction for the solution to my problem?
From the discussion in the answer from @JarvanZhang , since the tab bar is placed at the bottom of the page the bar is represented by a BottomNavigationView. I therefore need to apply the desired background style via a custom TabbedPage renderer.
In the renderer, override OnElementChanged as follows:
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
base.OnElementChanged(e);
if (e.NewElement == null) return;
// Identify first (only) bottom navigation view in collection of element children.
var bottomNavigationView = GetBottomNavigationView(ViewGroup);
// Apply a custom border style for the item background.
bottomNavigationView.ItemBackground =
Resources?.GetDrawable(Resource.Drawable.background_states, Context?.Theme);
where GetBottomNavigationView is a method for traversing the tree of element children and needs to be separately implemented (left out here for brevity). The drawable resource background_states is the selector used to apply different backgrounds depending on state.
Hello,
Welcome to our Microsoft Q&A platform!
TabbedPage corresponds to ViewPager on native Android. For ViewPager, the tab bar is displayed by TabLayout. So, we can define the appearance of the tabs via TabLayout. Try to define drawables for different selected state of the tab, and create a selector to consume the drawables. Then specify the selector as the tabBackground in styles.xml.
Here is the related code, you could refer to it.
drawable/tab_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/tab_selected_background" android:state_selected="true" />
<item android:drawable="@drawable/tab_unselected_background"
android:state_selected="false"
android:state_focused="false"
android:state_pressed="false" />
android:drawable="@drawable/tab_focused_background"
android:state_selected="false"
android:state_pressed="true"/>
</selector>
drawable/tab_focused_background.xml
<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#00FF00" />
</shape>
styles.xml
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="Base.Widget.Design.TabLayout" parent="android:Widget">
<item name="tabBackground">@drawable/tab_background</item>
</style>
</resources>
Best Regards,
Jarvan Zhang
If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Thanks, Jarvan this indeed seems useful. If I want to set the default style for the ViewPager/TabLayout in the app theme of my styles.xml file, what is the name of the style that I should override? That is, what should be used instead of XXX in the declarations below?
<style name="MyTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="XXX">@style/Base.Widget.Design.TabLayout</item>
</style>
Hi, AndersGustafsson-8878. Just place the TabLayout style to the styles.xml. Here is the complete code of the styles.xml, you could refer to it.
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MainTheme" parent="MainTheme.Base">
</style>
<style name="Base.Widget.Design.TabLayout" parent="android:Widget">
<item name="tabBackground">@drawable/tab_background</item>
</style>
</resources>
I sincerely appreciate the help, but unfortunately I cannot see any difference in the bar appearance, not even when I set the background to a simple solid color. I have migrated to AndroidX and I am targeting API Level 30, if that is of any relevance. I am concurrently using XAML to set the UnselectedTabColor and SelectedTabColor, respectively, also not sure if that interferes?
@JarvanZhang I just found the explanation why it is not working for me. According to the TabbedPageRenderer source code, the TabLayout is only used when the tab bar is placed at the top of the page. When it is placed in the bottom (as you can see above is the case for me), the tab bar is represented by a BottomNavigationView. If you have any input on how to change the background of the individual items in this BottomNavigationView via xml styles, I am still eager to find out.
Finally! I managed to set the BottomNavigationView.ItemBackground to the Drawable selector resource in my custom TabbedPageRenderer, and now it works! Thanks for leading me in the right direction, @JarvanZhang .
I still am interested how/if I can do this in the styles.xml file as well, so if you know how to do it feel free to post the alternative solution.