How can I change the background color of the Android tab with a renderer, while using a custom renderer to add some padding

痴心易碎 提交于 2020-08-27 12:07:50

问题


In my application I set the bottom tab bar background color like this:

<Shell xmlns="http://xamarin.com/schemas/2014/forms" 
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
       x:Class="M.Views.AppShell"
       NavBarIsVisible="True"
       xmlns:local="clr-namespace:Memorise"
       BackgroundColor="{DynamicResource ShellBackgroundColor}"
       TabBarBackgroundColor="{DynamicResource TabBarBackgroundColor}" 
       TabBarDisabledColor="{DynamicResource TabBarDisabledColor}" 
       TabBarForegroundColor="{DynamicResource TabBarForegroundColor}" 
       TabBarTitleColor="{DynamicResource TabBarTitleColor}" 
       TabBarUnselectedColor="{DynamicResource TabBarUnselectedColor}"

I create a custom renderer to add some side padding to the tabs on Android:

public class CustomShellRenderer : ShellRenderer
{
    public CustomShellRenderer(Context context)
        : base(context)
    {
    }

    protected override IShellBottomNavViewAppearanceTracker CreateBottomNavViewAppearanceTracker(ShellItem shellItem)
    {
        return new MarginedTabBarAppearance();
    }
}

public class MarginedTabBarAppearance : IShellBottomNavViewAppearanceTracker
{
    public void Dispose()
    {
    }

    public void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
    {
        if (App.devWidth == SIZE.L)
            bottomView.SetPadding(400, 0, 400, 0);
    }

    public void ResetAppearance(BottomNavigationView bottomView)
    {
    }
}

Unfortunately this also has a side effect in that it sets the background color of the tab to white.

Does anyone have any knowledge of how I use this renderer and also change the background color to be the same as the DynamicResource ShellBackgroundColor?

Code with renderers commented out:

public class CustomShellRenderer : ShellRenderer
{
    public CustomShellRenderer(Context context)
        : base(context)
    {
    }

    //protected override IShellBottomNavViewAppearanceTracker CreateBottomNavViewAppearanceTracker(ShellItem shellItem)
    //{
    //    return new MarginedTabBarAppearance();
    //}
}

public class MarginedTabBarAppearance : IShellBottomNavViewAppearanceTracker
{
    public void Dispose()
    {
    }

    public void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
    {
        //if (App.devWidth == SIZE.L)
        //    bottomView.SetPadding(400, 0, 400, 0);
        //if (Application.Current.Resources["TabBarBackgroundColor"] is Xamarin.Forms.Color color1)
        //{
        //    bottomView.SetBackgroundColor(color1.ToAndroid());
        //}
    }

    public void ResetAppearance(BottomNavigationView bottomView)
    {
    }
}

Tab bars with renderers commented out:

** Code with renderers not commented out:**

public class CustomShellRenderer : ShellRenderer
{
    public CustomShellRenderer(Context context)
        : base(context)
    {
    }

    protected override IShellBottomNavViewAppearanceTracker CreateBottomNavViewAppearanceTracker(ShellItem shellItem)
    {
        return new MarginedTabBarAppearance();
    }
}

public class MarginedTabBarAppearance : IShellBottomNavViewAppearanceTracker
{
    public void Dispose()
    {
    }

    public void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
    {
        if (App.devWidth == SIZE.L)
            bottomView.SetPadding(400, 0, 400, 0);
        if (Application.Current.Resources["TabBarBackgroundColor"] is Xamarin.Forms.Color color1)
        {
            bottomView.SetBackgroundColor(color1.ToAndroid());
        }
    }

    public void ResetAppearance(BottomNavigationView bottomView)
    {
    }
}

Tab bars with renderers not commented out:

Updated code suggested by Mihail:

public class MarginedTabBarAppearance :    ShellBottomNavViewAppearanceTracker
{

public MarginedTabBarAppearance(IShellContext shellContext, ShellItem shellItem)
    : base(shellContext, shellItem)
{
}

public override void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
{
    base.SetAppearance(bottomView, appearance);

    bottomView.SetPadding(400, 0, 400, 0);

    if (Application.Current.Resources.ContainsKey("TabBarBackgroundColor") && 
        Application.Current.Resources["TabBarBackgroundColor"] is Color tabColor)
    {
        bottomView.SetBackgroundColor(tabColor.ToAndroid());
    }
}
}

回答1:


In your SetAppearance method, you can set the background color like this:

bottomView.SetBackgroundColor(Android.Graphics.Color.Red);

However, the SetBackgroundColor requires a color of type Android.Graphics.Color and I see that you wish to take the color from a DynamicResource, which will return a Xamarin.Forms.Color. The good thing is that both color classes are easily convertable so we'll only need to take the current value of the DynamicResource:

if (Application.Current.Resources["CustomTabBackgroundColor"] is Xamarin.Forms.Color color)
{
    bottomView.SetBackgroundColor(color.ToAndroid());
}

Here, CustomTabBackgroundColor is the key for your color and color.ToAndroid() does the convertion between the 2 classes (from Xamarin's to Android's one).

UPDATE

Due to an update to the question, I'll add that the issue with the styles/colors resetting isn't in this case due to the backround change, but it's due to something else entirely. The way that a new view appearance is being set (return new MarginedTabBarAppearance();) resets all of the default styles. Since we are implementing everything from an interface and not deriving from the base class, we can't take anything from the already preset values. In order to fix that, we'll need to change the way the MarginedTabBarAppearance class is being implemented:

public class MarginedTabBarAppearance : ShellBottomNavViewAppearanceTracker
{
    public MarginedTabBarAppearance(IShellContext shellContext, ShellItem shellItem)
        : base(shellContext, shellItem)
    {
    }

    public override void SetAppearance(BottomNavigationView bottomView, IShellAppearanceElement appearance)
    {
        base.SetAppearance(bottomView, appearance);

        bottomView.SetPadding(400, 0, 400, 0);

        if (Application.Current.Resources.ContainsKey("TabBarBackgroundColor") && 
            Application.Current.Resources["TabBarBackgroundColor"] is Color tabColor)
        {
            bottomView.SetBackgroundColor(tabColor.ToAndroid());
        }
    }
}

Also, you will have to change your CreateBottomNavViewAppearanceTracker method like this:

protected override IShellBottomNavViewAppearanceTracker CreateBottomNavViewAppearanceTracker(ShellItem shellItem)
{
    return new MarginedTabBarAppearance(this, shellItem);
}

This way we'll take everything that we have already styled and we'll simply change what we'll need.




回答2:


Change the background color of TabBar with SetBackgroundColor method in SetAppearance.

Original screenshot:

Add the code in SetAppearance method:

bottomView.SetBackgroundColor(Android.Graphics.Color.Green);

Screenshot:



来源:https://stackoverflow.com/questions/62719511/how-can-i-change-the-background-color-of-the-android-tab-with-a-renderer-while

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!