在UWP中页面滑动导航栏置顶

简介: 原文:在UWP中页面滑动导航栏置顶最近在研究掌上英雄联盟,主要是用来给自己看新闻,顺便copy个界面改一下段位装装逼,可是在我copy的时候发现这个东西 当你滑动到一定距离的时候导航栏会置顶不动,这个特性在微博和淘宝都有,我看了@ms-uap的文章,淘宝的实现方式是改变顶部显示栏的大小,我本来准...
原文: 在UWP中页面滑动导航栏置顶

最近在研究掌上英雄联盟,主要是用来给自己看新闻,顺便copy个界面改一下段位装装逼,可是在我copy的时候发现这个东西

当你滑动到一定距离的时候导航栏会置顶不动,这个特性在微博和淘宝都有,我看了@ms-uap的文章,淘宝的实现方式是改变顶部显示栏的大小,我本来准备按照他那个思路去做的,但发现效果不理想,在滑动的时候,底部的界面也跟着在滑动,这样使得很不友好,所以我准备自己实现一个

先上个最终效果图吧,图比较大,请耐心等待

 

思路大概是这样的

将这个界面分为两行

<Grid.RowDefinitions>
            <!--第一行固定大小,用于放置图片和导航栏-->
            <RowDefinition Height="200"/>
            <RowDefinition/>
 </Grid.RowDefinitions>

然后放置我们的主要代码,Scrollview里包含一个pivot控件,将这个控件的title加上header的高设置为第一行的高度

<ScrollViewer x:Name="scroll" ViewChanged="scroll_ViewChanged" Grid.Row="0" Grid.RowSpan="2">
            <Pivot x:Name="pivot">
                <Pivot.Title>
                    <Grid Height="130"/>
                </Pivot.Title>
                <PivotItem>
                    <StackPanel>
                        <ListView >
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                            <x:Int32>1</x:Int32>
                        </ListView>
                    </StackPanel>
                </PivotItem>
                <PivotItem>
                    <StackPanel>
                        <ListView >
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                            <x:Int32>2</x:Int32>
                        </ListView>
                    </StackPanel>
                </PivotItem>
                <PivotItem>
                    <StackPanel>
                        <ListView >
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                            <x:Int32>3</x:Int32>
                        </ListView>
                    </StackPanel>
                </PivotItem>
            </Pivot>
        </ScrollViewer>

  这样,整个ScrollViewer占据了整个屏幕,然后我们来添加导航栏和他上面该显示的内容

 <Grid x:Name="header" Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="150"/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <!--图片-->
            <Grid Background="Green">
                
            </Grid>
            <!--导航栏 使用listbox绑定到pivot上-->
            <ListBox Grid.Row="1" x:Name="listBox"
                     Height="50"
                             HorizontalAlignment="Stretch"
                             VerticalAlignment="Bottom"
                             Background="#FFEAEAEA"
                             SelectedIndex="{Binding ElementName=pivot,
                                                     Path=SelectedIndex,
                                                     Mode=TwoWay}" >
                <ListBox.Items>
                    <TextBlock Text="战绩"/>
                    <TextBlock Text="能力"/>
                    <TextBlock Text="资产"/>
                </ListBox.Items>
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"></StackPanel>
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
            </ListBox>
        </Grid>

  这里同样是将其设置为两行,第一行用于显示其他内容,此处我就用一个Green色的Grid来代替了,然后第二行才是我们的重点,导航栏,这里我使用了ListBox绑定到pivot的selectedindex来实现,当pivot切换的时候,listbox的selecteditem也跟着切换,那这个时候就有疑问了,为什么不直接用pivot的Header来作为导航栏呢,因为当你把pivot套在scrollview里面是,这个header和title会一起跟着滚动的。

到这里,整个程序差不多快完成了,

回到后台代码,定义一个用于header平移变换的全局变量

TranslateTransform
 private TranslateTransform _tt;

  在界面初始化完成后初始化变量

 public MainPage()
        {
            this.InitializeComponent();
            //初始化平移对象
            _tt = header.RenderTransform as TranslateTransform;
            if (_tt == null)
            {
                header.RenderTransform = _tt = new TranslateTransform();
            }
        }

  然后就是这整个页面的行为了,我们给ScrllViewer控件添加一个ViewChanged时间

  //当scrollview 滚动时改变header的位置,使其往上移动
        private void scroll_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
        {
            //当滚动条到达导航栏时,停止移动
            if (scroll.VerticalOffset >= 150)
            {
                _tt.Y = -150;
            }
            else
            {
                _tt.Y = -scroll.VerticalOffset;
            }
        }

  在事件处理函数中改变header的位置使其往上移动,此时pivot控件也是一起跟着滑动,不过他的Header和Title的高度和导航栏的高度一致,所以会给人一种没有滑动的感觉。然后我们运行程序,发现鼠标滚轮在pivot里滚动的时候,sccrollview并没有反应,

那怎么办,这里我采用了路由事件来解决

在页面初始化之后,给pivot注册鼠标滚轮的路由事件

 public MainPage()
        {
            this.InitializeComponent();
            //给pivot注册 鼠标滚轮路由事件,否则鼠标滚轮的滑动 会变成切换pivotitem
            pivot.AddHandler(PointerWheelChangedEvent, new PointerEventHandler(OnChanged), true);
            //初始化平移对象
            _tt = header.RenderTransform as TranslateTransform;
            if (_tt == null)
            {
                header.RenderTransform = _tt = new TranslateTransform();
            }
        }

  然后添加处理函数

private void OnChanged(object sender, PointerRoutedEventArgs e)
        {
            //判断鼠标滚动方向
            if (e.GetCurrentPoint(pivot).Properties.MouseWheelDelta < 0)
            {
                scroll.ChangeView(0, scroll.VerticalOffset + 75, 1);
            }
            else
            {
                scroll.ChangeView(0, scroll.VerticalOffset - 75, 1);
            }
            e.Handled = true;
        }

  到这里我们的页面就完成了,上一个gif图展示

 

第一次写分享,写的不好请多多见谅

github源码地址:https://github.com/hei12138/FixedToHead

欢迎一起交流uwp的开发技术 1329698854@qq.com,

目录
相关文章
|
关系型数据库 MySQL
wget下载软件包时,遇到不信任问题,除了跳过证书检验,更新或者下载ca证书也是个解决办法
wget下载软件包时,遇到不信任问题,除了跳过证书检验,更新或者下载ca证书也是个解决办法
1353 0
|
8月前
|
SQL 存储 开发框架
ASPX+MSSQL注如;SQL盲注
在ASPX与MSSQL环境下,SQL注入和SQL盲注是常见且危险的攻击方式。通过参数化查询、输入验证、最小权限原则以及使用WAF等防御措施,可以有效防止此类攻击的发生。了解和掌握这些技术,对于提升应用程序的安全性至关重要。希望本文能为您提供有价值的信息和指导。
128 23
|
5月前
|
存储 SQL 自然语言处理
ClickHouse查询执行与优化
本文详细介绍了SQL语法扩展、执行计划分析及优化策略,涵盖特殊函数与子句(如`WITH`、`ANY JOIN`)、聚合函数扩展(如`uniqCombined`、`quantileTDigest`)以及执行计划优化技巧。同时深入解析了ClickHouse的索引原理,包括主键索引和跳数索引的工作机制与优化方法。针对查询优化,文章提供了过滤条件下推、分布式查询优化和数据预聚合等策略,并探讨了资源管理与并发控制的核心参数(如`max_memory_usage`、`max_threads`)及队列优先级调度机制,助力高效使用ClickHouse。
|
Python
Python函数式编程:你真的懂了吗?理解核心概念,实践高阶技巧,这篇文章带你一次搞定!
【8月更文挑战第6天】本文介绍了Python中的函数式编程,探讨了高阶函数、纯函数、匿名函数、不可变数据结构及递归等核心概念。通过具体示例展示了如何利用`map()`和`filter()`等内置函数处理数据,解释了纯函数的一致性和可预测性特点,并演示了使用`lambda`创建简短函数的方法。此外,文章还强调了使用不可变数据结构的重要性,并通过递归函数实例说明了递归的基本原理。掌握这些技巧有助于编写更清晰、模块化的代码。
171 3
'webpack-dev-server' 不是内部或外部命令,也不是可运行 的程序 或批处理文件。
'webpack-dev-server' 不是内部或外部命令,也不是可运行 的程序 或批处理文件。
377 0
|
JavaScript Java 测试技术
基于SpringBoot+Vue的BBS论坛系统的详细设计和实现
基于SpringBoot+Vue的BBS论坛系统的详细设计和实现
214 0
|
关系型数据库 MySQL 分布式数据库
什么是PolarDB MySQL企业版
PolarDB MySQL版是阿里巴巴自研的云原生HTAP数据库。PolarDB MySQL版100%兼容原生MySQL的多个版本,包括MySQL 5.6、MySQL 5.7和MySQL 8.0。PolarDB MySQL版的企业版基于云原生架构、计算存储分离、软硬件一体化设计,为用户提供具备超高弹性和性能、高可用和高可靠保障、高性价比的数据库服务。 产品架构
302 0
如何用牛顿法求一个数的平方根
(一)导数与导函数 导数 设函数y=f(x)在点x0的某个邻域内有定义,当自变量x在x0处有增量Δx,(x0+Δx)也在该邻域内时,相应地函数取得增量Δy=f(x0+Δx)-f(x0);如果Δy与Δx之比当Δx→0时极限存在,则称函数y=f(x)在点x0处可导,并称这个极限为函数y=f(x)在点x0处的导数记作①f'(x0) ;②y'│x=x0 ;③ │x=x0, 即 导函数 如果函数y=f(x)在开区间内每一点都可导,就称函数f(x)在区间内可导。
4323 1
|
存储 关系型数据库 MySQL
PolarDB-X V2.3 集中式和分布式一体化开源发布
本文主要介绍PolarDB-X V2.3 集中式和分布式一体化开源。