Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

[F100] Translucent Nav Bar #1698

Closed
PureWeen opened this issue Jan 26, 2018 · 17 comments
Closed

[F100] Translucent Nav Bar #1698

PureWeen opened this issue Jan 26, 2018 · 17 comments

Comments

@PureWeen
Copy link
Contributor

Rationale

Currently when setting the navigation bar to Translucent requires a custom renderer. In addition the Xamarin Forms content pages don't account for the extra space now created by the translucent bar. Having a property on the NavigationBar to allow it to be transparent and then having the content flow correctly would be useful

Implementation

public static readonly BindableProperty IsTranslucentProperty =
     BindableProperty.Create(propertyName: nameof(IsTranslucent),
	     returnType: typeof(bool), declaringType: typeof(NavigationPage), defaultValue: false);
		 

Navigation Renderer will set the Nav Bar to be translucent and then the contained pages will fill all available space

Expected Result

Android

  • NavigationPage.IsTranslucent = true: Should cause the navigation bar to become translucent. Content Pages should shifted and measured as if the Navigation Bar doesn't exist

iOS

See Android

UWP

See Android

Implications for CSS

Not sure if this translates to the same concept as making the navbar translucent as "translucents" also has content flow implications. Could possibly map opacity >= 0.5 to setting the IsTranslucent Property to true

navigationpage {opacity: 0.5; } 

Backward Compatibility

Third party renderers may need to be updated to ensure that this functionality is supported through the new official mechanism. Further we will need to be careful to code the changes to the renderers in a careful manner to ensure that if someone is already using an effect support this feature that the effect is as best as possible not broken by our changes.

Difficulty : Medium

https://bugzilla.xamarin.com/show_bug.cgi?id=24500

@rmarinho
Copy link
Member

@llevera
Copy link

llevera commented Jan 31, 2018

@rmarinho It would appear that is only for iOS? This may be because on Android a translucent status bar is ordinarily done through themes which will be challenging to achieve with Xamarin Forms....

@bentmar
Copy link
Contributor

bentmar commented Feb 7, 2018

androiddraw
I added an attachableprop to NavigationPage (bool) and adjusted the layout depending on it in NavigationPageRenderer, it works just like the HasNavigationBar property.
But this is for android only, would you even accept a PR that just covers one platform or is it better if i make is as a platformspecific property?

What you see is 2 pages, one with DrawBehind = true and one false.
I change the color from blue to transparent when navigating

@jassmith jassmith self-assigned this Feb 16, 2018
@vividos
Copy link

vividos commented Mar 19, 2018

I was searching for an Android implementation of a translucent NavigationPage toolbar and found this PR: #1287 It seems to handle the Android side of things. Looking forward to having this in Xamarin.Forms 3.0 :-)

@jelle-vdst
Copy link

@bentmar I would like to implement the same effect on android as you showed in your post, do you have any source code for this? (if you are willing to share ofcourse)

@jelle-vdst
Copy link

@bentmar
Nevermind, already found it myself :)

@yunusefendi52
Copy link

@jelle-vdst do you mind to share? I haven't found it yet.

@jelle-vdst
Copy link

@5yunus2efendi

I've made a custom navigationPage adding a Translucent (bool) property and a translucent change event

then i've made a custom navigation renderer and overridden the OnLayout like this:

`protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
base.OnLayout(changed, l, t, r, b);

        if (!((NavigationExPage)Element).TranslucentToolbar)
            return;

            AToolbar bar = _toolbar;

        int containerHeight = b - t;

        int barHeight = _actionbarHeight;

        var pageController = Element;
        pageController.ContainerArea = new Rectangle(0, 0, Context.FromPixels(r - l), Context.FromPixels(containerHeight));


        for (var i = 0; i < ChildCount; i++)
        {
            AView child = GetChildAt(i);

            if (child is AToolbar)
                return;

            bar.Layout(0, -1000, r, barHeight - 1000);
            child.Layout(0, 0, r, b);
        }

    }`

I've also added this:

` public NavigationPageExRenderercs(Context context) : base(context)
{
_color = Color.ParseColor("#2196F3");
_standardTextColor = Xamarin.Forms.Color.White;
}

    protected override void OnElementChanged(ElementChangedEventArgs<NavigationPage> e)
    {
        base.OnElementChanged(e);
        if (e.NewElement != null)
        {
            ((NavigationExPage) e.NewElement).TranslucentChange += ColorSwitch;
        }
        if (e.OldElement != null)
        {
            ((NavigationExPage)e.OldElement).TranslucentChange -= ColorSwitch;
        }
    }

    private void ColorSwitch(object sender, EventArgs e)
    {
        for (var i = 0; i < ChildCount; i++)
        {
            AView toolbar = GetChildAt(i);

            if (toolbar is AToolbar)
            {
                if (((NavigationExPage)Element).TranslucentToolbar)
                {
                    Element.BarTextColor = Xamarin.Forms.Color.Transparent;
                    toolbar.SetBackgroundColor(Color.Transparent);
                }
                else
                {
                    Element.BarTextColor = _standardTextColor;
                    toolbar.SetBackgroundColor(_color);
                }

            }
        }
    }


    public override void OnViewAdded(View child)
    {
        base.OnViewAdded(child);

        if (((NavigationExPage)Element).TranslucentToolbar)
        {
            if (child is AToolbar)
            {
                var toolbar = (AToolbar)child;
                toolbar.SetBackgroundColor(Color.Transparent);
                GetToolbar();
                _actionbarHeight = ActionBarHeight();
            }
        }
    }

    

    private void GetToolbar()
    {
        Context context = Context;
        var activity = (FormsAppCompatActivity)context;

        AToolbar bar;
        if (FormsAppCompatActivity.ToolbarResource != 0)
            bar = activity.LayoutInflater.Inflate(FormsAppCompatActivity.ToolbarResource, null).JavaCast<AToolbar>();
        else
            bar = new AToolbar(context);

        _toolbar = bar;
    }

    private int ActionBarHeight()
    {
        int attr = Resource.Attribute.actionBarSize;

        int actionBarHeight;
        using (var tv = new TypedValue())
        {
            actionBarHeight = 0;
            if (Context.Theme.ResolveAttribute(attr, tv, true))
                actionBarHeight = TypedValue.ComplexToDimensionPixelSize(tv.Data, Resources.DisplayMetrics);
        }

        if (actionBarHeight <= 0)
            return Device.Info.CurrentOrientation.IsPortrait() ? (int)Context.ToPixels(56) : (int)Context.ToPixels(48);

        if (((Activity)Context).Window.Attributes.Flags.HasFlag(WindowManagerFlags.TranslucentStatus) || ((Activity)Context).Window.Attributes.Flags.HasFlag(WindowManagerFlags.TranslucentNavigation))
        {
            if (_toolbar.PaddingTop == 0)
                _toolbar.SetPadding(0, GetStatusBarHeight(), 0, 0);

            return actionBarHeight + GetStatusBarHeight();
        }

        return actionBarHeight;
    }

    int GetStatusBarHeight()
    {
        if (_statusbarHeight > 0)
            return _statusbarHeight;

        int resourceId = Resources.GetIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0)
            _statusbarHeight = Resources.GetDimensionPixelSize(resourceId);

        return _statusbarHeight;
    }`

The ActionBarHeight and GetToolBar method i've copied out of the xamarin forms renderer (based all my code on what happens in the standard renderer). The code still needs to be optimized (for example switching from a page with translucent to a page without is not smooth yet, it's still a work in progress)

@yunusefendi52
Copy link

@jelle-vdst It works!, thanks.

@adrianknight89
Copy link
Contributor

@jelle-vdst I wouldn't write such custom code to create a translucent navigation bar as it is likely that it will be interfering with how XF is laying out controls (now or in the future). Xamarin should support this functionality out of the box.

@bentmar With regards to DrawBehind, this works nicely if the page has already appeared and you can toggle this property on and off which most people most likely wouldn't.

A more complicated scenario should be supported by XF. Suppose one page set DrawBehind to false while the one to be pushed on the stack set it to true. What will switching from false to true look like if the page transition animation was custom on Android? Suppose it was more like iOS where pages enter in from the right and exit to the right. How will DrawBehind work with this transition?

@rmarinho If I'm not mistaken, iOS transcluency does not get rid of the navbar as in the case of @bentmar's DrawBehind gif even if BarBackgroundColor is transparent, so I believe this enhancement proposal is going to be similar to how iOS is working now.

@jelle-vdst
Copy link

@adrianknight89 I agree, but I need the functionality right now, the moment it's supported, I'll kick out my custom renderer. But right now I need it, I only need the transparency on one page and it works smootly for the moment.

@nhdanh
Copy link

nhdanh commented Jul 4, 2018

@jelle-vdst Can you share me your navigationbar renderer make for this ?

@pcdus
Copy link

pcdus commented Jul 5, 2018

@jelle-vdst I thought that the translucent navbar was already available with XF3, as we can see this in the ConferenceVision Xamarin sample. But they used a similar approach to yours. Do we know when this feature will be officially supported? And would you have a Github project that describes your implementation?

@pcdus
Copy link

pcdus commented Jul 5, 2018

I've implemented the solution found in the ConferenceVision sample, but I meet a strange behavior that I describe there: the rendering is not the same between iOS 10.1 and iOS 11.3. If you have any suggestion, you're welcome!

@SagarPanwala
Copy link

Guys,
Any update on this ?

@samhouts samhouts changed the title [Enhancement] Translucent Nav Bar [F100] Translucent Nav Bar Jun 3, 2019
@samhouts samhouts added this to the 4.3.0 milestone Jun 4, 2019
@samhouts samhouts modified the milestones: 4.3.0, 4.4.0 Aug 29, 2019
@samhouts samhouts modified the milestones: 4.4.0, 4.5.0 Nov 20, 2019
@samhouts samhouts added inactive Issue is older than 6 months and needs to be retested help wanted We welcome community contributions to any issue, but these might be a good place to start! up-for-grabs We welcome community contributions to any issue, but these might be a good place to start! labels Nov 22, 2019
@samhouts samhouts added proposal-open and removed help wanted We welcome community contributions to any issue, but these might be a good place to start! up-for-grabs We welcome community contributions to any issue, but these might be a good place to start! labels Feb 7, 2020
@samhouts samhouts removed this from the 4.5.0 milestone Feb 11, 2020
@Softtinn
Copy link

Any news on this one?

@jfversluis
Copy link
Member

I think some of this is now possible? There won't be any work done on this for Xamarin.Forms though. If this is something people are still interested in, please open an feature request on the .NET MAUI repo.

Thanks for you interest and input everyone!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests