在看过一篇文章

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. MVC扩展HtmlHelper,加入RadioButtonList、CheckBoxList、DropdownList

    代码: using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions ...

  2. 201621123008 《Java程序设计》第五周学习总结

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 关键词:接口,内部类. 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需要出现过多的字. 1.3 可选:使用常 ...

  3. pkg_config找不到库

    解决方法 假设libavutil默认安装时libavutil.pc安装到了 /usr/lib64/lib/pkgconfig/ 中,而 echo $PKG_CONFIG_PATH 结果中没有这个路径, ...

  4. 设计规范VS设计创造力,谁更胜一筹?

    设计规范和设计创造力哪个更重要?这是一个颇具争议性的话题.如果是3年前问我这个问题我会毫不犹豫的选择设计创造力,毫无疑问,一个好的设计创造力真的是可以让人像打了鸡血一样疯狂. 原来在上大学的时候,我就 ...

  5. mathematica9激活

    1.打开m9软件 2.打开keygen软件 3.点手动输入验证码,输入里面的id到keygen软件再点save mathpath 4.复制keygen软件里面 的mathpass到 将生成的mathp ...

  6. Eclipse 中 Could not find *.apk的解决方案

    Eclipse 中 Could not find *.apk的解决方案 有时候debug的时候出现Could not find *.apk 特别是导入别人的例子的时候 1.选择properties-& ...

  7. 2018秋季C语言基础课第1次作业

    1.翻阅邹欣老师博客关于师生关系博客,并回答下列问题: 1)大学和高中最大的不同是没有人天天看着你,请看大学理想的师生关系是?有何感想? 答:是  Coach / Trainee (健身教练 / 健身 ...

  8. 2018.09.24 bzoj4977: [[Lydsy1708月赛]跳伞求生(贪心+线段树)

    传送门 线段树好题. 这题一看我就想贪心. 先把a,b数组排序. 然后我们选择a数组中最大的b个数(不足b个就选a个数),分别贪心出在b数组中可以获得的最大贡献. 这时可以用线段树优化. 然后交上去只 ...

  9. 2018.08.18 NOIP模拟 snow(最大流)

    Snow 题目背景 SOURCE:NOIP2015-SHY4 题目描述 有一天,TT 要去 ABC 家.ABC 的大门外有 n 个站台,用 1 到 n 的正整数编号,TT 需要对每个站台访问恰好一定次 ...

  10. Python网络编程总结

    ----learn from luffycity---- 1. 什么是C/S架构? C指的是client(客户端软件),S指的是Server(服务端软件),C/S架构就是基于网络实现客户端与服务端通信 ...