Xamarin android C# ScrollView OnScrollChanged event

本文关键字:OnScrollChanged event ScrollView android Xamarin | 更新日期: 2023-09-27 18:34:20

在Xamarin Android中,我们如何扩展ScrollView以使用受保护的OnScrollChanged事件?

具体说来我们如何扩展 ScrollView 以允许将事件处理程序注册到 OnScrollChanged 事件?在扩展 ScrollView 的类中还需要实现哪些其他 ScrollView 方法?

原因:

Android ScrollView 无法侦听滚动事件。关于如何在原生Android Java中扩展ScrollView,已经存在各种问题,但是,没有一个问题和答案来解决如何将其应用于Xamarin。

Xamarin android C# ScrollView OnScrollChanged event

为了以这种方式扩展 ScrollView,我们应该实现 3 个构造函数

public UsefulScrollView(Context context)
public UsefulScrollView(Context context, IAttributeSet attrs)
public UsefulScrollView(Context context, IAttributeSet attrs, int defStyle)

我们还需要重写 OnDraw 方法

protected override void OnDraw(Android.Graphics.Canvas canvas)

为了实现我们可以在用户滚动时响应的事件的功能,我们需要重写 OnScrollChanged 方法。

protected override void OnScrollChanged(int l, int t, int oldl, int oldt)

有多种方法可以允许事件侦听和处理,但为了与 Xamarin 保持一致,我们可以向类添加公共事件处理程序属性。

public EventHandler<T> ScrollEventHandler { get; set; }

我们需要将值从 OnScrollChanged 传递到 EventHandler,所以让我们扩展 EventArgs

public class UsefulScrollEventArgs : EventArgs{
    public int l { get; set; }
    public int t { get; set; }
    public int oldl { get; set; }
    public int oldt { get; set; }
}

最后,不要忘记在每个构造函数中初始化我们的处理程序

ScrollEventHandler = (object sender, UsefulScrollEventArgs e) => {};

把它们放在一起,它可能看起来像这样

扩展事件参数类

public class UsefulScrollEventArgs : EventArgs{
    public int l { get; set; }
    public int t { get; set; }
    public int oldl { get; set; }
    public int oldt { get; set; }
}

扩展滚动视图类

public class UsefulScrollView : ScrollView
{
    public EventHandler<UsefulScrollEventArgs> ScrollEventHandler { get; set; }
    public UsefulScrollView (Context context)
    : base(context)
    {
        ScrollEventHandler = (object sender, UsefulScrollEventArgs e) => {};
    }
    public UsefulScrollView (Context context, IAttributeSet attrs)
    : base(context, attrs) {
        ScrollEventHandler = (object sender, UsefulScrollEventArgs e) => {};
    }
    public UsefulScrollView(Context context, IAttributeSet attrs, int defStyle)
    : base(context, attrs, defStyle) {
        ScrollEventHandler = (object sender, UsefulScrollEventArgs e) => {};
    }
    protected override void OnScrollChanged(int l, int t, int oldl, int oldt)
    {
        ScrollEventHandler (this, 
                   new UsefulScrollEventArgs ()
                   {l=l,t=t,oldl=oldl,oldt=oldt});
        base.OnScrollChanged (l, t, oldl, oldt);
    }
    protected override void OnDraw(Android.Graphics.Canvas canvas)
    {
    }
}

这个问答有助于解决这个问题:Scrollview侦听器在Xamarin for Android中不起作用?

我扩展了ScrollView,但使用了EventHandlers。一个用于滚动更改,一个用于到达底部。

这在您的扩展类中:

    public delegate void ScrollChangedEventHandler(object sender, EventArgs e);
    public event ScrollChangedEventHandler ScrollChanged;
    public delegate void ScrollReachedBottomEventHandler(object sender, EventArgs e);
    public event ScrollReachedBottomEventHandler ScrollReachedBottom;
    protected override void OnScrollChanged(int l, int t, int oldl, int oldt)
    {
        base.OnScrollChanged(l, t, oldl, oldt);
        if (ScrollChanged != null)
        {
            ScrollChanged.Invoke(this, new EventArgs());
        }
        // Grab the last child placed in the ScrollView, we need it to determinate the bottom position.
        var view = GetChildAt(ChildCount - 1);
        // Calculate the scrolldiff
        var diff = (view.Bottom - (Height + ScrollY));
        // if diff is zero, then the bottom has been reached
        if (diff == 0 && ScrollReachedBottom != null)
        {
            ScrollReachedBottom.Invoke(this, new EventArgs());
        }
    }

然后,您只需致电

myScrollView.ScrollChanged += delegate { /* your code here */ }

myScrollView.ScrollReachedBottom += delegate { /* your code here */ }

享受。