在看过一篇文章

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. My97DatePicker 日历控件

    My97DatePicker 是一款非常强大的日历控件,使用也非常简单,也能修改源码,牛逼我就不吹了,自己用用看 使用 1.引入 <script language="javascrip ...

  2. VC++ 定时器使用总结

    VC++    WM_TIMER   定时器使用方法       在编程时,会经常使用到定时器.使用定时器的方法比较简单,通常告诉Windows一个时间间隔,然后WINDOWS以此时间间隔周期性触发程 ...

  3. 用AI制作炫酷效果

    PART1:制作第一个效果 步骤一:新建一个800*600的画布. 骤二:从工具栏选“矩形工具”,创建一个800*600的矩形.白色的是画布,浅红色(我的AI之前保留的填充颜色,每个人都不一样)的是你 ...

  4. jquery获取radio单选框的值

    1.获取原有单选框的值 var value=$("input[name='is_setting']:checked").val(); 2.获取重选后的单选框的值 <tr> ...

  5. FTP 搭建

    FTP 搭建 FTP 是 File Transfer Protocol(文件传输协议)的英文简称,它工作在 0SI 模型的第七层,TCP 模型的第四屋上,即应用层. 一.FTP 简介 FTP 会话时包 ...

  6. 对于cnn的理解

    对于神经网络就是给他一个网络各个层之见的传导函数, 之所以这里面用卷积来替代普通的放射函数, 就是因为卷积算的快,hadmard 乘机比矩阵乘法的速度快一个次方,可能都不止. 对于高清晰度的图片算矩阵 ...

  7. 百度词汇检索,计算PMI值

    '''词汇检索百度返回值,并且计算PMI值的类''' from bs4 import BeautifulSoup import requests import re import pandas as ...

  8. 26. The Greenhouse Effect and Its Consequences 温室效应及其后果

    26. The Greenhouse Effect and Its Consequences 温室效应及其后果 ①The greenhouse effect causes trouble by rai ...

  9. C#打印日志的小技巧

    public static void Log(params System.Object[] message) { string str = ""; if (message == n ...

  10. AVL树C++实现

    1. AVL 树本质上还是一棵二叉搜索树,它的特点是: 本身首先是一棵二叉搜索树. 带有平衡条件: 每个结点的左右子树的高度之差的绝对值(平衡因子) 最多为 1. 2. 数据结构定义 AVL树节点类: ...