Xamarin.Form 下拉刷新动画

好像园子里对 Xamarin 感兴趣的人很少啊...

来, 先给各位爷们逗个笑, 本山大爷本色出演:

 

照例, 上源码:

https://github.com/gruan01/ListViewExtend

目前只有 WP 的效果, Android 还在研究, IOS 的还没计划.

 

------------------------------------------------------

Xamarin.Form 的 ListView 只支持下拉刷新 (这里有用法), 上拉 加载更多 没有对应的事件. 这个先放一边, 今天先说说 WP 下, ListView 的下拉动画效果的替换.

 

用反编译工具查看 ListViewRenderer 

Xamarin.Form 下拉刷新动画_第1张图片

 

OnElementChanged 中, 声明了一个 FixedLongListSelector 的控件, 然后将这个控件设为 NativeControl, 并对这个控件的 PullToRefreshXXXX 事件设置处理程序.

我的目的很简单, 就是替换掉下拉动画. 所以这几个事件必定是入口点.

FixedLongListSelector 继承自 LongListSelector, 很不幸, 它是 internal 的! 不过没关系, 用反射也很容易.

 

用反射清理/新增事件处理程序: 

private void ClearEventHandlers(object obj, string evtName) {
            var t = obj.GetType();
            //var fs = t.GetFields(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);

            var evt = t.GetEvent(evtName);
            var f1 = t.GetField(evtName, BindingFlags.NonPublic | BindingFlags.Instance);
            if (evt != null && f1 != null) {
                var handler = (EventHandler)f1.GetValue(obj);
                var ds = handler.GetInvocationList();
                evt.RemoveEventHandler(obj, handler);
            }
        }

        private void AddEventHandler(object obj, string evtName, Delegate handler) {
            var t = obj.GetType();
            var evt = t.GetEvent(evtName);
            evt.AddEventHandler(obj, handler);
        }

 

 昨天有个面试的说他用的很多反射, 我随口就问了如何用反射清理已存在的事件处理程序, 并新增自已的处理程序, 小伙闸想了半天没回答上来 , 我是不是有点那个啊...

 

能清理和新增事件处理程序还不够, WP 的 LongListSelector 不自带下拉动画效果, XF 是通过新增一个 ProgressBar 来做的这个效果, 如下:

Xamarin.Form 下拉刷新动画_第2张图片

这个 ProgressBar 默认是不可见的 (progressBar.Visibility = Visibility.Collapsed;), PullToRefreshXXXX事件的处理程序会跟据相关的属性, 对这个 ProgressBar 做更新, 已达到上面图上所示的动画效果.

知道了这些, 那就好办了, 我们额外定义一个 ListView 的渲染器:

https://github.com/gruan01/ListViewExtend/blob/master/ListViewExtend/ListViewExtend.WinPhone/Renders/ListViewRender.cs

自己声明一个 UIElement 对象, 通过 this.Children.Add(xxx) , 添加进来, 然后在自己的事件处理程序里对这个对象做动画播放与停止.

 1 protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e) {
 2     base.OnElementChanged(e);
 3     ...
 4     ...
 5     this.Grid.Children.Add(this.Viewbox);
 6     this.Viewbox.Child = this.Border;
 7     this.Children.Add(this.Grid);
 8     ...
 9     this.SB = new SA.Storyboard() {
10         Duration = new Duration(TimeSpan.FromMilliseconds(1000)),
11         AutoReverse = true,
12         RepeatBehavior = SA.RepeatBehavior.Forever
13     };
14     ...
15     ...
16     this.OverrideEvents();
17 }

 

 

        private void UpdateIsRefreshing() {
            this.Grid.Visibility = this.Element.IsRefreshing ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
            if (this.Element.IsRefreshing)
                this.SB.Begin();
            else
                this.SB.Stop();
        }

 

代码很简单, 其它部分不在在赘述.

动画效果丑了点, 只做参考..

 

另外, 反编译了一下 Android 的 ListViewRenderer,  它的下拉刷新是通过 SwipeRefreshLayout 来实现的.

这个控件自带动画效果. 搜了一下, 好像它不能重写动画, 只能设置几个颜色....这就不好办了...

 

你可能感兴趣的:(form)