博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
15、导航滑动动画
阅读量:5159 次
发布时间:2019-06-13

本文共 7377 字,大约阅读时间需要 24 分钟。

 

  在触屏设备上,手指滑动页面,或者单击导航选项时,增加导航下横线滑动的效果:

  这个版本有点简单粗暴,同事在项目中优化了一下算法。这里只是简单记录一下大致思路:

 

1、导航使用 ListView 控件,下面使用 Pivot 控件

  大致结构为:

 

页面中的 ListView:

              

 

选中时,播放的位移动画:

 

Pivot 中,重写 Template,去掉 Header 等多余对象:

View Code

 

 

2、事件操作

1)大致思路是,当手指滑动屏幕时,通过 Pivot 中 ScrollViewer 的 ViewChanging 事件,来横向移动选中 Item 中红色的矩形(Rectangle),当动画结束时,再重置当前的 Rectangle 的位移。

如果单击 ListView 中的 Item,则直接在它的 SelectionChanged 事件中,计算前一个 Rectangle 和新 Rectangle 的相对位置,来播放位移动画。

2) code behind 中的代码:

public sealed partial class MainPage : Page    {        public MainPage()        {            this.InitializeComponent();            this.Loaded += MainPage_Loaded;        }        private void MainPage_Loaded(object sender, RoutedEventArgs e)        {            this.Loaded -= MainPage_Loaded;            // 绑定到匿名类型上            pivot.ItemsSource = listview.ItemsSource = new []{ new { Text = "军事" } , new { Text = "科技" }, new { Text = "国内新闻" },new { Text = "娱乐" }, new { Text = "国际新闻" }, new { Text = "相声" }, new { Text = "体育赛事" },  new { Text = "综艺" } };            listview.SelectedIndex = 0;                    }        #region 横向 Rectangle 的位移        Rectangle rect_old; // 上一次选中的 Rectangle        Rectangle rect_current; // 当前选中的 Rectangle        double posi_previous; // 手指点击屏幕时,记录当前的 pivot 中 ScrollViewer.HorizontalOffset        ScrollViewer pivot_sv;        bool IsMoving = false;//手指是否在滑动中        private void listView_SelectionChanged(object sender, SelectionChangedEventArgs e)        {            if (firstRectInited == false) return;            // 如果是当前显示项,则显示“下横线”            for (int i = 0; i < listview.Items.Count; i++)            {                if (listview.ContainerFromIndex(i) != null)                {                    var grid = (listview.ContainerFromIndex(i) as ListViewItem).ContentTemplateRoot as Grid;                    var rect = grid.FindName("rect") as Rectangle;                    (rect.RenderTransform as CompositeTransform).TranslateX = 0;// 重置横向位移为 0                    if (listview.SelectedIndex == i) // 当前选中项                    {                        listview.ScrollIntoView(listview.SelectedItem);//当滑动 pivot 时,如果 ListView选中项不在视图内,则显示                        rect_old = rect_current;                        rect_current = rect;                        if (IsMoving == false) // 非手指划动 pivot                        {                            Rect_Slide();                            listview.IsHitTestVisible = false; // 当“划动动画”在播放的时候,不再接受单击事件                        }                    }                    if (IsMoving)                        rect.Opacity = listview.SelectedIndex == i ? 1 : 0;//选中项显示下横向,否则隐藏                }            }            IsMoving = false;        }        //播放划动动画        void Rect_Slide()        {            if (rect_old != null && rect_current != null)            {                // 如果设置 Width 属性,可能会导致列表宽度发生变化,所以这里使用 Scale来缩放下横线                (rect_old.RenderTransform as CompositeTransform).ScaleX = rect_current.ActualWidth / rect_old.ActualWidth;                var old_rect = GetBounds(rect_old, listview);                var new_rect = GetBounds(rect_current, listview);                // 获取 ListView 单击后,两个 Item之间的距离                SB_Slide_TransX.KeyFrames[1].Value = new_rect.X - old_rect.X;                Storyboard.SetTarget(SB_Slide_TransX, rect_old);                SB_Slide.Begin();            }        }        // 获取子元素相对于父元素的左边        public Rect GetBounds(FrameworkElement childElement, FrameworkElement parentElement)        {            GeneralTransform transform = childElement.TransformToVisual(parentElement);            return transform.TransformBounds(new Rect(0, 0, childElement.ActualWidth, childElement.ActualHeight));        }        // 滑动动画结束时,重置参数        private void SB_Slide_Completed(object sender, object e)        {            listview.IsHitTestVisible = true;            rect_old.Opacity = 0;            (rect_old.RenderTransform as CompositeTransform).ScaleX = 1;            rect_current.Opacity = 1;            SB_Slide.Stop();        }        // 手指横向移动 Pivot 时,更改下横向的位移        private void ScrollViewer_ViewChanging(object sender, ScrollViewerViewChangingEventArgs e)        {            if (IsMoving && rect_current != null && pivot_sv != null)                (rect_current.RenderTransform as CompositeTransform).TranslateX = (pivot_sv.HorizontalOffset - posi_previous) / pivot_sv.ActualWidth * rect_current.ActualWidth;        }        // 手指开始触摸屏幕时        private void ScrollViewer_DirectManipulationStarted(object sender, object e)        {            IsMoving = true;            pivot_sv = sender as ScrollViewer;            posi_previous = pivot_sv.HorizontalOffset;        }        // 查找第一个 Rectangle        bool firstRectInited = false;        private void rect_Loaded(object sender, RoutedEventArgs e)        {            var r = sender as Rectangle;            r.Loaded -= rect_Loaded;            if (!firstRectInited  && listview.ContainerFromIndex(0) != null)            {                var grid = (listview.ContainerFromIndex(0) as ListViewItem).ContentTemplateRoot as Grid;                rect_current = grid.FindName("rect") as Rectangle;                rect_current.Opacity = 1;                firstRectInited = true;            }        }        #endregion            }

 

 

转载于:https://www.cnblogs.com/hebeiDGL/p/5657527.html

你可能感兴趣的文章
IntelliJ IDEA 开发swing(二)
查看>>
十五天精通WCF——第十二天 说说wcf中的那几种序列化
查看>>
【.net深呼吸】动态类型(高级篇)
查看>>
javascript运算符整理
查看>>
消除类游戏(js版)
查看>>
【javascript基础】5、创建对象
查看>>
跟我一起学习ASP.NET 4.5 MVC4.0(六)
查看>>
IBM RSA (IBM rational software architect ) V8 学习之六 C++类模板设计
查看>>
SQL SERVER 2008 EXPRESS版本远程连接(tcp/ip)
查看>>
asp.net开源CMS推荐
查看>>
查询数据库里有多少张表、视图、存储过程
查看>>
Python和qqbot库开发简单的机器人
查看>>
Smarty foreach添加论坛楼层计数(counter)
查看>>
BOM之history对象(转)
查看>>
maven项目正常运行,项目图标打红叉叉解决方法(个人笔记)
查看>>
软件工程(2018)第二次团队作业
查看>>
GoLang执行需要输入密码的命令
查看>>
一款古老的 Scheme 编译器,一台古老的“机器”
查看>>
Centos 配置eth0 提示Device does not seem to be present
查看>>
值类型,引用类型,装箱,拆箱
查看>>