Xamarin android C#ScrollView OnScrollChanged事件

时间:2014-12-16 16:36:45

标签: c# android xamarin scrollview onscrolllistener

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

具体而言, 我们如何扩展ScrollView以允许将EventHandler注册到OnScrollChanged事件? ScrollView的其他哪些方法需要在扩展ScrollView的类中实现?

原因:

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

2 个答案:

答案 0 :(得分:3)

为了以这种方式扩展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保持一致,我们可以向我们的类添加一个公共EventHandler属性。

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) => {};

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

扩展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; }
}

扩展ScrollView类

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)
    {

    }
}

此Q&amp; A有助于解决此问题:Scrollview listener is not working in Xamarin for Android?

答案 1 :(得分:1)

我扩展了ScrollView但使用了EventHandlers。一个用于ScrollChanged,一个用于ReachedBottom。

这适用于您的扩展课程:

    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 */ }

享受。