【问题标题】:Xamarin android C# ScrollView OnScrollChanged eventXamarin android C# ScrollView OnScrollChanged 事件
【发布时间】:2015-02-15 01:14:54
【问题描述】:

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

具体来说, 我们如何扩展 ScrollView 以允许将 EventHandler 注册到 OnScrollChanged 事件? ScrollView还有哪些方法需要在继承ScrollView的类中实现?

原因:

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

【问题讨论】:

    标签: c# android xamarin scrollview onscrolllistener


    【解决方案1】:

    为了以这种方式扩展 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)
        {
    
        }
    }
    

    这个问答有助于解决这个问题:Scrollview listener is not working in Xamarin for Android?

    【讨论】:

      【解决方案2】:

      我扩展了 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 */ }
      

      享受吧。

      【讨论】:

        猜你喜欢
        • 2017-07-15
        • 2011-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-02
        • 1970-01-01
        相关资源
        最近更新 更多