Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scrolling to start of Xamarin Forms ListView with header

I'm having some trouble scrolling to the top of a ListView in Xamarin Forms. I can scroll to the first item by calling ScrollTo and passing the first item. The problem is that when the list has a header item, I can't find a way to scroll to the header. Is this possible? The only work around I can think of is to not use the header and just have another item at the start of the ItemSource list that acts as a header but I'd rather use the header if possible. Thanks.

like image 938
Gareth Wynn Avatar asked Apr 21 '16 11:04

Gareth Wynn


2 Answers

So I've solved this myself now. My solution was to subclass ListView and add a public ScrollToTop method which invokes an internal ScrollToTopRequestedEvent when called. I then subclassed the ListViewRenderer on each platform and registered for the event.

In the Android renderer I'm then calling Control.SmoothScrollToPositionFromTop(0, 0) to scroll to top.

In the iOS rendered I'm calling Control.ScrollRectToVisible(new CoreGraphics.CGRect(0, 0, 1, 1), true).

like image 135
Gareth Wynn Avatar answered Nov 14 '22 09:11

Gareth Wynn


Wah all credits @Gareth Wynn, man that was cool thx. Anyway here's the code for everyone to use, change class names and namespace, iOS not included, do same as for Android just using Gareth Wynn's hint in parallel answer:

SHARED NiftyListView.cs :

        using System;
        using Xamarin.Forms;

            namespace AppoMobi
            {
                public class NiftyListView : CListView
                {
                    public event EventHandler EventScrollToTop;

                    //-------------------------------------------------------------------
                    public void ScrollToTop(bool animate=true)
                    //-------------------------------------------------------------------
                    {
                        //bool animate is not used at this stage, it's always animated.
                        EventScrollToTop?.Invoke(this, EventArgs.Empty);
                    }
                }
            }

ANDROID NiftyListView.Android.cs :

using System;
using AppoMobi;
using AppoMobi.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using ListView = Xamarin.Forms.ListView;

[assembly: ExportRenderer(typeof(NiftyListView), typeof(NiftyListViewRenderer))]
namespace AppoMobi.Droid.Renderers
{
    //-------------------------------------------------------------------
    class NiftyListViewRenderer : ListViewRenderer
    //-------------------------------------------------------------------
    {
        protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
        {
            base.OnElementChanged(e);

            var view = (NiftyListView)Element;
            if (view == null) return;

            view.EventScrollToTop += OnScrollToTop;

        }

        //-------------------------------------------------------------------------------------------
        public async void OnScrollToTop(object sender, EventArgs eventArgs)
        //-------------------------------------------------------------------------------------------
        {
            Control.SmoothScrollToPositionFromTop(0, 0);
        }

    }
}
like image 34
Nick Kovalsky Avatar answered Nov 14 '22 09:11

Nick Kovalsky