简体   繁体   中英

Xamarin.Forms MasterDetail page NavBar customization

I'm in need of a large dose of help for an issue with the MasterDetail page in Xamarin.Forms .

What I'm trying to do is, very simply, to customize the NavigationBar 's background to use a gradient. My setup is a Xamarin.Forms app with Prism , where I first login the user and then navigate to a MasterDetail page like so:

await NavigationService.NavigateAsync("MyMasterDetailPage/NavigationPage/MyDetailPage")

The problem I am running into is that no matter what I do I can't change the color of the NavigationBar .

I've tried several different variants of CustomRenderers (for Android currently), as well as just adding a custom TitleView to the Detail page in the PCL project. I've also tried changing the styles.xml file, changing the ToolBar.axml to use the drawable I've made, but I've still got no luck so far.

Any help would be greatly appreciated as I've been struggling for a few days now with this issue.

Below is a screenshot of what's going on:

在此处输入图片说明

Toolbar.axml:

<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:popupTheme="@style/ThemeOverlay.AppCompat.Light"
android:background="@drawable/gradient_background_drawable"
 />

styles.xml:

<?xml version="1.0" encoding="utf-8" ?>
<resources>

  <style name="MainTheme" parent="MainTheme.Base">
  </style>
  <!-- Base theme applied no matter what API -->
  <style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
    <!--If you are using revision 22.1 please use just windowNoTitle. Without android:-->
    <item name="windowNoTitle">true</item>
    <!--We will be using the toolbar so no need to show ActionBar-->
    <item name="windowActionBar">false</item>
    <!-- Set theme colors from http://www.google.com/design/spec/style/color.html#color-color-palette -->
    <!-- colorPrimary is used for the default action bar background -->
    <item name="colorPrimary">#89D362</item>
    <!-- colorPrimaryDark is used for the status bar -->
    <item name="colorPrimaryDark">#89D362</item>
    <!-- colorAccent is used as the default value for colorControlActivated
         which is used to tint widgets -->
    <item name="colorAccent">#FF4081</item>
    <!-- You can also set colorControlNormal, colorControlActivated
         colorControlHighlight and colorSwitchThumbNormal. -->
    <!--<item name="windowActionModeOverlay">true</item>-->

    <item name="android:datePickerDialogTheme">@style/AppCompatDialogStyle</item>
    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
  </style>

  <style name="AppCompatDialogStyle" parent="Theme.AppCompat.Light.Dialog">
    <item name="colorAccent">#FF4081</item>
  </style>

  <style name="DrawerArrowStyle" parent="@style/Widget.AppCompat.DrawerArrowToggle">
    <item name="spinBars">true</item>
    <item name="color">#89D362</item>
  </style>
</resources>

gradient_background_drawable:

<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
  <gradient android:type="linear"
            android:angle="270"
            android:startColor="#000E0E"
            android:endColor="#3D3939">
  </gradient>

</shape>

MasterDetailPageRenderer:

protected override void OnLayout(bool changed, int l, int t, int r, int b)
        {
            base.OnLayout(changed, l, t, r, b);
            var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
            if (toolbar != null)
            {
                for (int i = 0; i < toolbar.ChildCount; i++)
                {
                    var child = toolbar.GetChildAt(i);
                    child.Background = Context.GetDrawable(Resource.Drawable.gradient_background_drawable);
                }

                toolbar.Background = Context.GetDrawable(Resource.Drawable.gradient_background_drawable);
            }
        }

NavigationPageRenderer:

protected override void OnElementChanged(ElementChangedEventArgs<NavigationPage> e)
        {
            base.OnElementChanged(e);
            if (e.OldElement != null || Element == null)
            {
                return;
            }

            var actionBar = ((FormsAppCompatActivity)Context).SupportActionBar;
            actionBar.SetBackgroundDrawable(Context.GetDrawable(Resource.Drawable.gradient_background_drawable));
        }

        protected override void OnLayout(bool changed, int l, int t, int r, int b)
        {
            base.OnLayout(changed, l, t, r, b);
            var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
            if (toolbar != null)
            {
                //for (int i = 0; i < toolbar.ChildCount; i++)
                //{
                //    var child = toolbar.GetChildAt(i);
                //    child.Background = Context.GetDrawable(Resource.Drawable.gradient_background_drawable);
                //}

                toolbar.Background = Context.GetDrawable(Resource.Drawable.gradient_background_drawable);
            }
        }

        public override void OnViewAdded(Android.Views.View child)
        {
            base.OnViewAdded(child);
            if (child.GetType() == typeof(Android.Support.V7.Widget.Toolbar))
            {
                _toolbar = (Android.Support.V7.Widget.Toolbar)child;

                _toolbar.Background = Context.GetDrawable(Resource.Drawable.gradient_background_drawable);
            }
        }

I achieved the function by creating a new app with template Master-Detail Page . The method is to set the background of Toolbar.axml just as you mentioned.

<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:popupTheme="@style/ThemeOverlay.AppCompat.Light" 
android:background="@drawable/gradient_background_drawable"
/>

To make the effect more obvious,I change the gradient color. You can change back to your own gradient color.

file gradient_background_drawable.xml

<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
  <gradient android:type="linear"
            android:angle="270"
            android:startColor="#008B00"
            android:endColor="#9AFF9A">
  </gradient>
</shape>

Besides,remember to remove the Property relatived with Background about toolbar in file App.xaml .

file App.xaml

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FormApp202011.App">
    <Application.Resources>
        <ResourceDictionary>
            <!--Global Styles  -->
            <Color x:Key="NavigationPrimary">#2196F3</Color>
            <Style TargetType="NavigationPage">
                <Setter Property="BarTextColor" Value="Red" />

            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

The result:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM