Sticky Header o Sticky Navigation Bar en Xamarin.Forms

Contenido

Si te has preguntado anteriormente como crear un StickyHeader (Cabecera Pegajoza o Adhesiva) o StickyNavigationBar (Barra de Navegación Pegajoza o Adhesiva) en Xamarin.Forms entonces estas en el lugar correcto.

En este articulo compartiré contigo un control personalizado del CollectionView para utilizar el evento Scrolled del mismo y al encapsular toda la lógica relacionada a nuestro caso de uso, que en esta ocasión es la Pagina de Perfil de Instagram donde se muestra una lista de imágenes en grilla con varios tabs para cambiar el contexto.

💡 Nota: Tambien puedes utilizar un ScrollView con su evento Scrolled y todo funcionara de la misma manera.

Entendiendo el StickyHeader

StickyHeader o StickyNavigation se refiere a tener elementos de diseño que están permanentemente en las pantallas de los usuarios, incluso cuando se desplazan hacia abajo en una vista. Si bien esto estaba reservado principalmente para la barra de navegación en un inicio, pero estamos viendo elementos como los botones flotantes y otros elementos que se han convertido en elementos pegajosos populares utilizados en el diseño de aplicaciones móviles.

Creando el StickyHeader

En el articulo anterior les mostré un caso particular y muy popular donde podríamos necesitar cambiar de contextos o utilizar vistas que hagan scroll pero que compartan el mismo header. Esta es la pagina de usuario de Instagram. Vamos a verla:

Este header cuando hacemos scroll hacia abajo se queda pegado en la parte superior. Y si hacemos scroll hasta su posición inicial, empieza a hacer scroll con los demás elementos.

Custom CollectionView con StickyHeader

En el anterior articulo, hable un poco sobre como crear un collectionView con varios contextos de datos que comparten un mismo header o cabecera, si no lo has visto te recomiendo que le eches un ojo para que lo entiendas un poco.

Para lograr esto hemos definido algunos parámetros por defecto como:

  • StickyHeader, de tipo View, recibe la instancia de la vista que estaremos utilizando como header pegajoso y tiene un valor por defecto de null.
  • CustomHeader, de tipo View, recibe la instancia de la vista que estaremos utilizando como header y tiene un valor por defecto de null.
  • SecondContent, de tipo View, recibe la instancia de la vista que estaremos utilizando como contenido secundario y tiene un valor por defecto de null.


Con estos parámetros podemos tener un CustomCollactionView de la siguiente manera:

    public class CustomCollectionView : CollectionView
    {
...
        [TypeConverter(typeof(ReferenceTypeConverter))]
        public View CustomHeader
        {
            set
            {
                _customHeader = value;
                _customHeader.SizeChanged += (o, e) => this.Header = new BoxView() { HeightRequest = _customHeader.Height };                
            }
        }

        [TypeConverter(typeof(ReferenceTypeConverter))]
        public View StickyHeader
        {
            set => _sticyHeader = value;
        }

        [TypeConverter(typeof(ReferenceTypeConverter))]
        public View SecondContent
        {
            set => _secondContent = value;
        }

        private async void GoodCollectionView_Scrolled(object sender, ItemsViewScrolledEventArgs e)
        {
            double scrollY = e.VerticalOffset < 0 ? 0 : e.VerticalOffset;
            double minimumHeight = _customHeader.Height - _sticyHeader.Height;

            scrollY = scrollY > minimumHeight ? minimumHeight : scrollY;

            //Show or hide the header and scroll the second view
            await Task.WhenAll(_customHeader?.TranslateTo(0, -scrollY, 50), 
                _secondContent?.TranslateTo(0, -scrollY + _customHeader.Height, 50));
        }
    }

Cada vez que se haga scroll dentro de nuestro CollectionView calculados el scrollY y animamos la transición del header y el contenido secundario al mismo tiempo. De igual manera establecemos los limites de transición para que nuestra cabecera pegajosa siempre se muestre en la vista.

Nota: Hay una limitante. El control crea automáticamente un Header dentro del CollectionView, si creas un header sera sobre escrito por nuestro código y agregara un BoxView para simular el Margen del control. Si quieres usar un Header dentro del CollectionView solo establece un alto fijo a tu Header y a tu fila dentro Grid donde posicionas el header.

Una vez tenemos el control, lo podemos utilizar en nuestros proyectos de Xamarin Forms. Aquí un ejemplo en XAML:

...
    <Grid>

        <ctrls:CustomCollectionView
            x:Name="collectionView"
            Grid.RowSpan="2"
            CustomHeader="myCustomHeader"
            StickyHeader="myStickyHeader"
            ItemSizingStrategy="MeasureFirstItem"
            ItemsLayout="VerticalGrid, 3"
            ItemsSource="{Binding Images}"
            SecondContent="mySecondView">

            <CollectionView.ItemTemplate>
                <DataTemplate>
                        ...
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </ctrls:GoodCollectionView>

        <!-- YOUR VIEWS GOES HERE -->

        <StackLayout x:Name="myCustomHeader" VerticalOptions="Start">
            ...
            <!-- YOUR STICKY HEADER GOES HERE -->
        </StackLayout>

    </Grid>
...

Con esto podemos obtener un comportamiento similar al de la pagina de perfil de Instagram con nuestra cabecera pegajosa. Veamos un ejemplo:

CollectionView dentro de un ScrollVIew con StickyHeader.
Nota: El header mostrado no pertenece al CollectionView.

Conclusión

Espero que este articulo de sea de utilidad, y nada déjenme saber en las redes que realmente les gusta este tipo de artículos y yo hare lo posible por darles lo mejor de lo mejor.

Ayuda a crecer nuestra comunidad y desbloquea el contenido debajo para acceder al repo de ejemplo. ⬇⬇⬇

Sin nada mas que agregar, ¡Nos vemos en la próxima!

¿Qué opinas de este contenido?
 
Luis Matos

Luis Matos

I help professionals and companies to create value solutions. I am a Systems Engineer, blockchain executive, and international mobile application speaker. Founder of the Malla Consulting Agency and several international technology communities.
Suscribirte
Notificar de
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x

Buscar en el sitio