Search code examples
c#xamlmaui

Scrollable Header in .Net MAUI


I want to design a header that decrease in size when the user scrolls upwards and sticks to the top. The design I'm going for is one that shows a logo in the header that corvers about 50% of the screen. However, upon scroll, it decreases to about 20% of its original size and changes into a title text.

I have tried using a frame but still can't achieve this.


Solution

  • Creating a scrollable header that dynamically changes size in .NET MAUI can be achieved by using a combination of ScrollView, AbsoluteLayout for positioning, and event handling to detect scrolling. You'll need to listen for the scroll event and adjust the size of the header and the logo accordingly.

    Here is an example of how you might write the XAML and C# code to achieve this effect:

    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="YourNamespace.YourPage"
             x:Name="thisPage">
    <ScrollView x:Name="scrollView"
                Scrolled="OnScrollViewScrolled">
        <VerticalStackLayout>
            <!-- This is the header -->
            <AbsoluteLayout x:Name="header"
                            HeightRequest="200"  <!-- Initial height -->
                            BackgroundColor="LightGray">
                <Image Source="your_logo.png"
                       AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
                       AbsoluteLayout.LayoutFlags="All"
                       Aspect="AspectFit"
                       x:Name="headerLogo"/>
                <Label Text="Your Title"
                       FontSize="Large"
                       AbsoluteLayout.LayoutBounds="0.5, 0.5, -1, -1"
                       AbsoluteLayout.LayoutFlags="PositionProportional"
                       IsVisible="False"
                       x:Name="headerTitle"/>
            </AbsoluteLayout>
    
            <!-- The rest of your page content goes here -->
            <!-- ... -->
        </VerticalStackLayout>
    </ScrollView>
    
    public partial class YourPage : ContentPage
    {
        public YourPage()
        {
            InitializeComponent();
        }
    
        private void OnScrollViewScrolled(object sender, ScrolledEventArgs e)
        {
            const double startHeight = 200; // The initial height of the header
            const double endHeight = 40;    // The final height of the header when scrolled
            double scrollRatio = Math.Min(1, e.ScrollY / startHeight);
    
            // Calculate new height based on the scroll ratio
            double newHeight = startHeight - ((startHeight - endHeight) * scrollRatio);
            header.HeightRequest = newHeight;
    
            // Determine whether the logo or the title should be visible
            headerLogo.IsVisible = newHeight > endHeight;
            headerTitle.IsVisible = newHeight <= endHeight;
        }
    }