2018正版葡京赌侠诗uwp ListView列表滑动特效

   在看过一篇文章  

WPF自定义控件之列表滑动特效 PowerListBox  http://www.cnblogs.com/ShenNan/p/4993374.html\#3619585 落成了滑动的特效(就是动画)之后 ,觉得很有趣 也想在 UWP里面已毕。最好效能如下2018正版葡京赌侠诗 1

接下去就说说是怎么落到实处的呢:

一. 添加 Behaviors

  右键项目 选中 “管理 NuGet
程序包”2018正版葡京赌侠诗 2

接下来搜索 Behaviors 添加2018正版葡京赌侠诗 3

 

 二 . 添加一个新的类

      这一个类就叫

ListViewBehavior 

吧 继承 DependencyObject, 继承接口 IBehavior
然后出示三番五次那一个接口的多少个点子

  public class ListViewBehavior : DependencyObject, IBehavior
    {
        public DependencyObject AssociatedObject { get; set; }

        public void Attach(DependencyObject associatedObject)
        {
            throw new NotImplementedException();
        }

        public void Detach()
        {
            throw new NotImplementedException();
        }
    }

接下来在这么些类里面添加一些质量,等会会用到

  public DependencyObject AssociatedObject { get; set; }

        /// <summary>
        /// 需要做动画的列表
        /// </summary>
        public ListView ListView;

        /// <summary>
        /// listView 里面的滚动条
        /// </summary>
        public ScrollViewer scroll;

          /// <summary>
          /// 容器的布局方向
           /// </summary>
            private Orientation _panelOrientation;

        /// <summary>
        /// 当前可视化视图的第一项
        /// </summary>
        private int firstVisibleIndex;

        /// <summary>
        /// 当前可视化视图的最后一项
        /// </summary>
        private int lastVisibleIndex;

        /// <summary>
        /// 上次滚动时可视化视图的第一项
        /// </summary>
        private int oldFirstVisibleIndex;

        /// <summary>
        /// 上次滚动时可视化视图的最后一项
        /// </summary>
        private int oldLastVisibleIndex;

        /// <summary>
        /// 标识,是否已找到第一项
        /// </summary>
        private bool isFindFirst;

        /// <summary>
        /// 当前累计已遍历过的Item高度或宽度的值,用于寻找第一项和最后一项
        /// </summary>
        private double cumulativeNum;




        public void Attach(DependencyObject associatedObject)
        {

        }

        public void Detach()
        {

        }

属性都准备好了那我们前天早先进入标准的一而再吧 , 在 Attach
方法里面添加代码

public void Attach(DependencyObject associatedObject)
        {
           //获取 ListView 列表对象
            ListView = associatedObject as ListView;

            if (ListView ==null )
            {
                return;
            }

            //传进来的 对象不为空,我们就对这个对象注册一个事件
            ListView.Loaded += ListView_Loaded;
        }

ListView_Lodaded 代码:

 /// <summary>
        /// 列表对象加载完成后的逻辑代码
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListView_Loaded(object sender, RoutedEventArgs e)
        {
            //查找滚动视图,并赋值到我们刚刚添加的属性里
            scroll = FindVisualChild<ScrollViewer>(ListView, "ScrollViewer");
            //判断是否为空,不为空的话就添加一个事件
            if (scroll == null)
            {
                return;
            }
            else
            {
                //监听滚动事件
                scroll.ViewChanged += Scroll_ViewChanged;
            }

             ItemsPresenter v =
FindVisualChild<ItemsPresenter>(ListView, “”);

             ItemsStackPanel items =
FindVisualChild<ItemsStackPanel>(v,””);

             _panelOrientation = items.Orientation;

        }

 /// <summary>
        /// 获取模板控件
        /// </summary>
        /// <typeparam name="T">获取的类型</typeparam>
        /// <param name="obj">控件对象</param>
        /// <returns></returns>
        protected T FindVisualChild<T>(DependencyObject obj, string name) where T : DependencyObject
        {
            //获取控件可视化树中的子对象数量
            int count = VisualTreeHelper.GetChildrenCount(obj);

            //根据索引遍历每一个对象
            for (int i = 0; i < count; i++)
            {
                var child = VisualTreeHelper.GetChild(obj, i);
                //根据参数判断是不是我们要找的对象,如果是 就返回,并退出该方法,
                //如果不是则再递归到下一层查找
                if (child is T && ((FrameworkElement)child).Name == name)
                {
                    return (T)child;
                }
                else
                {
                    var child1 = FindVisualChild<T>(child, name);

                    if (child1 != null)
                    {
                        return (T)child1;
                    }


                }
            }

            return null;

        }

 

现行早已获取到了 列表的 ScrollViewer 对象了 就足以实施那么些动画最中央的片段了,就是通过监听 滚动事件 来得到大家需求做动画的控件了。

 /// <summary>
        /// 监听滚动事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Scroll_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
        {
            //每次滚动时都计算当前可视化区域的首尾项
            CalculationIndex();
        }

再添加多个字段

 /// <summary>
        /// 列表子控件的高度
        /// </summary>
        private double itemsHeight;
        //平移特效对象
        private TranslateTransform tt;

  /// <summary>
        /// 计算可视化区域的第一项和最后一项
        /// </summary>
        private void CalculationIndex()
        {
            //赋值旧的第一个可视化视图
            oldFirstVisibleIndex = firstVisibleIndex;
            //赋值最后一个可视化视图
            oldLastVisibleIndex = lastVisibleIndex;

            ;
            //标记第一项是否找到了
            isFindFirst = false;
            //判断列表的方向
            if (_panelOrientation == Orientation.Vertical)
            {
                cumulativeNum = 0.0;


                //遍历列表的全部可视化视图,寻找第一项和最后一项
                for (int i = 0; i < ListView.Items.Count; i++)
                {


                    //转换成 ListViewItem 对象,用于操作
                    var _item = ListView.ContainerFromIndex(i) as ListViewItem;

                    //这里有个坑,应为 ListView 支持虚拟化的,所以每次获取列表的
                    //子项最多只会有20项左右,所以我们要记录一下 高度,将所遍历到的
                    //可视化视图的高度累加。

                    if (_item == null)
                    {

                        cumulativeNum += itemsHeight;
                    }
                    else
                    {
                        itemsHeight = _item.ActualHeight;
                        cumulativeNum += _item.ActualHeight + _item.Margin.Top + _item.Margin.Bottom;

                    }
                    //判断当前所累加的高度大于我们滚动的距离找到 现在显示在屏幕上的第一项
                    if (!isFindFirst && cumulativeNum >= scroll.VerticalOffset)
                    {
                        //记录第一项的索性
                        firstVisibleIndex = i;
                        //表明第一项已经找到了
                        isFindFirst = true;

                        Up();
                    }

                    //当前所累加的高度 大于 当前移动的距离和 滚动视图的可见高度,找出最后一项
                    if (cumulativeNum >= (scroll.VerticalOffset + scroll.ViewportHeight))
                    {
                        //记录最后一项的索引
                        lastVisibleIndex = i;

                        Down();

                        //已经找到的第一项和最后一项了 跳出循环
                        break;
                    }


                    ;

                }
            }

        }

 

末段 四个举办动画的章程:

  /// <summary>
        /// 滚动条向下,类容向上移动
        /// </summary>
        private void Down()
        {

            if ((firstVisibleIndex == oldFirstVisibleIndex && lastVisibleIndex == oldLastVisibleIndex) || oldFirstVisibleIndex == 0 && oldLastVisibleIndex == 0)
                return;

            //判断 当前最后一项 是否大于上次移动的最后一项
            if (lastVisibleIndex > oldLastVisibleIndex)
            {
                //获取可视化对象
                var _item = ListView.ContainerFromIndex(lastVisibleIndex) as ListViewItem;
                //
                tt = new TranslateTransform();

                //这里要判断一下 当前可视化是否为空,如果你移动得比较快的化,列表的虚拟化会给不到对象来的。
                if (_item == null)
                {
                    return;
                }


                _item.RenderTransform = tt;

                Storyboard board = new Storyboard();

                //创建一个 double 动画
                DoubleAnimation animation = new DoubleAnimation() { AutoReverse = false, RepeatBehavior = new RepeatBehavior(1), EnableDependentAnimation = true, To = 0, From = _item.ActualWidth / 2, Duration = TimeSpan.FromSeconds(0.2) };
                Storyboard.SetTarget(animation, tt);
                Storyboard.SetTargetProperty(animation, nameof(TranslateTransform.X));

                board.Children.Add(animation);

                board.Begin();




            }
        }

        /// <summary>
        /// 滚动条向上,内容向下
        /// </summary>
        private void Up()
        {
            if (firstVisibleIndex < oldFirstVisibleIndex)
            {
                var _item = ListView.ContainerFromIndex(firstVisibleIndex) as ListViewItem;

                tt = new TranslateTransform();
                if (_item == null)
                {
                    return;
                }
                _item.RenderTransform = tt;



                Storyboard board = new Storyboard();


                DoubleAnimation animation = new DoubleAnimation() { AutoReverse = false, RepeatBehavior = new RepeatBehavior(1), EnableDependentAnimation = true, To = 0, From = _item.ActualWidth / 2, Duration = TimeSpan.FromSeconds(0.3) };
                Storyboard.SetTarget(animation, tt);
                Storyboard.SetTargetProperty(animation, nameof(TranslateTransform.X));

                board.Children.Add(animation);

                board.Begin();


            }
        }

 

其一了类已经到位了最终我们在前台调试一下吧:前台代码:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <ListView x:Name="listView"   >
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem" >
                    <Setter Property="HorizontalContentAlignment" Value="Stretch" ></Setter>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  >
                        <Rectangle Height="100" Fill="Red"  HorizontalAlignment="Stretch"  Margin="5" ></Rectangle>
                        <TextBlock Text="{Binding }" FontSize="50" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="20" ></TextBlock>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>




            <interactivity:Interaction.Behaviors>
                <local:ListViewBehavior></local:ListViewBehavior>
            </interactivity:Interaction.Behaviors>
        </ListView>


    </Grid>

就这样我们就成功了一个滚动列表特效了,我们可以在 Down 和 Up
这七个法子里面修改其动画效果可以变得更其酷点,
率先次写博客。。。。。。。呜呜呜

发表评论

电子邮件地址不会被公开。 必填项已用*标注