在看过一篇文章

WPF自定义控件之列表滑动特效 PowerListBox  http://www.cnblogs.com/ShenNan/p/4993374.html#3619585 实现了滑动的特效(就是动画)之后 ,觉得很有趣 也想在 UWP里面实现。最好效果如下

接下来就说说是怎么实现的吧:

一. 添加 Behaviors

右键项目 选中 “管理 NuGet 程序包”

然后搜索 Behaviors 添加

二 . 添加一个新的类

这个类就叫

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 = ; 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 = ; 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 == && oldLastVisibleIndex == )
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(), EnableDependentAnimation = true, To = , From = _item.ActualWidth / , 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(), EnableDependentAnimation = true, To = , From = _item.ActualWidth / , 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="" Fill="Red" HorizontalAlignment="Stretch" Margin="" ></Rectangle>
<TextBlock Text="{Binding }" FontSize="" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="" ></TextBlock>
</Grid>
</DataTemplate>
</ListView.ItemTemplate> <interactivity:Interaction.Behaviors>
<local:ListViewBehavior></local:ListViewBehavior>
</interactivity:Interaction.Behaviors>
</ListView> </Grid>

就这样我们就完成了一个滚动列表特效了,大家可以在 Down 和 Up 这两个方法里面修改其动画效果可以变得更加酷点,
第一次写博客。。。。。。。呜呜呜

uwp ListView列表滑动特效的更多相关文章

  1. WPF自定义控件之列表滑动特效 PowerListBox

    列表控件是应用程序中常见的控件之一,对其做一些绚丽的视觉特效,可以让软件增色不少. 本人网上看过一个视频,是windows phone 7系统上的一个App的列表滚动效果,效果非常炫 现在在WPF上用 ...

  2. Android一个ListView列表之中插入两种不同的数据

    http://www.cnblogs.com/roucheng/ Android一个ListView列表之中插入两种不同的数据 代码如下: public class ViewHolder{ Butto ...

  3. 【转】Android 实现ListView的滑动删除效果

    http://www.cnblogs.com/weixiao870428/p/3524055.html http://download.csdn.net/download/love_javc_you/ ...

  4. [置顶] android 自定义ListView实现动画特效

    通过自定义ListView实现动画特效,被点击元素A向前移,A之前元素往后移动. 重点在于动画的实现: 具体代码如下: package com.open.widget; import java.uti ...

  5. ListView列表拖拽排序

    ListView列表拖拽排序能够參考Android源代码下的Music播放列表,他是能够拖拽的,源代码在[packages/apps/Music下的TouchInterceptor.java下]. 首 ...

  6. Android 开源库StickyListHeadersListView来实现ListView列表分组效果

    项目中有一新的需求,要求能像一些Android机带"联系人列表"一样,数据可以自动分组,且在列表滑动过程中,列表头固定在顶部,效果图如下: 下面就带大家实现上面的效果, 首先,我们 ...

  7. 基于slideout.js实现的移动端侧边栏滑动特效

    HTML5现在本领太大了,PC端已经无法满足它的胃口了,它将强势攻入移动端,所以移动端中各种特效也得基于HTML5实现,看看我们将要介绍的slideout.js,能帮我们实现怎么样的侧边栏滑动特效呢~ ...

  8. Android 使用NineOldAndroids实现绚丽的ListView左右滑动删除Item效果

    本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/18311877) 今天还是给大家带来自定义控件的编写,自定义一个Lis ...

  9. Android项目开发全程(四)-- 将网络返回的json字符串轻松转换成listview列表

    前面几篇博文介绍了从项目搭建到获取网络字符串,对一个项目的前期整体工作进行了详细的介绍,本篇接着上篇介绍一下怎么样优雅将网络返回的json字符串轻松转换成listview列表. 先上图,看一下效果. ...

随机推荐

  1. 验证二叉查找树 · Validate Binary Search Tree

    [抄题]: [思维问题]: 不知道要定义resultType, 其实用仔细分析判断条件就行了:是否是bst+最大最小值 类似于平衡二叉树:是否平衡+左右的高度差 [一句话思路]: [输入量]:空: 正 ...

  2. centos7.5配置双网卡上网

    一.环境及说明 当初有这个需求,主要是帮一个高校的客户搭建一个大数据集群,使用的是校园网,交换机上一个端口只能连接一部电脑上网,不能通过路由组建子网,确保集群中的服务器有子网ip的同时,也能够通过公网 ...

  3. Ubuntu --- not enough free disk space

    Ubuntu系统更新时出现not enough free disk space. 原因是系统的就内核占满了/boot 的空间,只要将旧内核删除就ok了 首先,命令 uname -r  查看当前内核,( ...

  4. 帧动画布局文件 animation-list

    <?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android=&qu ...

  5. 解决ios手机页面overflow scroll滑动很卡的问题

    在移动端html中经常出现横向/纵向滚动的效果,但是在iPhone中滚动速度很慢,感觉不流畅,有种卡卡的感觉,但是在安卓设备上没有这种感觉; 要解决这个问题很简单: 一行代码搞定 -webkit-ov ...

  6. qstring转string

    Qt的QString功能丰富,对非英语语言的支持也不是问题,但支持得不够直接.例如,像 1 QString str("死亡使者赛维"); 这样直接用带中文的字符串进行构造,那么用Q ...

  7. Vagrant WinNFSd

    Vagrant WinNFSd Manage and adds support for NFS on Windows. Supported Platforms As of version 1.0.6 ...

  8. Spring官方文档翻译(1~6章)

    Spring官方文档翻译(1~6章) 转载至 http://blog.csdn.net/tangtong1/article/details/51326887 Spring官方文档.参考中文文档 一.S ...

  9. JavaScript 静态方法和实例方法

    总结: 直接定义在构造函数上的方法和属性是静态的,  定义在构造函数的原型和实例上的方法和属性是非静态的 静态方法: function ClassA(){ //定义构造函数 }; ClassA.fun ...

  10. hdu-1066(大数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1066 思路:统计2的个数,如果遇到5,就抵消,最后求和加上为来得及抵消的2的个数. 参考文章:http ...