在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的开发技术 [email protected],

时间: 2025-01-15 05:27:30

在UWP中页面滑动导航栏置顶的相关文章

导航栏置顶固定悬浮

<!doctype html><html><head><meta charset="utf-8"><title>网友分享jQuery导航菜单悬浮置顶特效</title><style type="text/css"> *{ margin:0; padding:0;} body{ background:#eee; text-shadow:0px 1px 0px rgba(255,255,

【Andord实战】SlideMenu+ViewPagerIndictor滑动侧边双栏+滑动导航栏

采用SlideMenu实现侧边栏的效果: 其中 setContentView是设置主背景的布局 setBehindContentView是设置左边菜单的布局 setSecondaryMenu是设置右边的布局 setShadowWidth是设置阴影的宽度 setBehindWidth是设置有效的拉出宽度 setMode是设置开启左右两边的菜单 采用ViewPagerIndictor实现滑动的导航栏和页面布局 其中采用TabPageIndicator做可滑动导航栏 ViewPager做滑动的布局 首

ios 导航栏透明, 上下滑动 导航栏 颜色渐变

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px "PingFang SC"; color: #008400 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #3d1d81 } p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Menlo; color: #008400 } p.p4 {

滑动导航栏(PagerSlidingTabStrip)实践

本篇介绍另一个开源项目滑动导航栏(PagerSlidingTabStrip). 开源项目PagerSlidingTabStrip地址: https://github.com/astuetz/PagerSlidingTabStrip 全例程代码实现: 1). activity: /** * 滑动导航栏(PagerSlidingTabStrip)test * */ public class MainActivity extends FragmentActivity { private Fragmen

Jquery给当前页或者跳转后页面的导航栏添加选中后样式

解决方法有两种:一种是直接给当前页面添加特殊样式,当网页刷新或者跳转到下一页后,样式消失:另一种情况是即使刷新页面后样式仍然有效. 直接上代码: 第一种情况: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <script type="text/javascript" src="templets/js/jquery.js"></script>  <script type=&qu

UWP中使用Composition API实现吸顶(2)

原文:UWP中使用Composition API实现吸顶(2) 在上一篇中我们讨论了不涉及Pivot的吸顶操作,但是一般来说,吸顶的部分都是Pivot的Header,所以在此我们将讨论关于Pivot多个Item关联同一个Header的情况. 老样子,先做一个简单的页面,页面有一个Grid当Header,一个去掉了头部的Pivot,Pivot内有三个ListView,ListView设置了和页面Header高度一致的空白Header. <Page x:Class="TestListViewH

原生js实现导航栏吸顶

实现滑动滚动条让导航栏吸顶原理:主要是通过监听scroll,设定一个滚动条垂直位移作为临界,让导航栏吸顶或者取消吸顶. 话不多说了,代码如下: window.onscroll = function () { var scrollT = document.documentElement.scrollTop || document.body.scrollTop; // 滚动条的垂直偏移 if (scrollT > xx) { //xx为临界的垂直位移值 //修改导航栏的样式,让他呈现吸顶的状态 主要

父子控制器中的自定义导航栏

提到自定义导航栏,大家首先想到的就是自己写个自定义导航控制器,然后设置自己的导航控制器的主题.再把包装着自己控制器的导航控制器的class填上自己写的自定义nav如果遇到个别控制器的导航栏想与众不同,就再写个自定义nav然后再弄个新的导航控制器包裹自己. 可是,如果一个项目中用到了 父子控制器,上面的这种做法就会没有效果.原因就是取不到导航栏. 比如我做的大概架构是一个collectionView的循环引用,让一个个tableview都是包装在我的collectionViewcell里面的,然后

利用Jquery给当前页或者跳转后页面的导航栏添加选中后样式

当鼠标选中页面导航栏的某一栏目后,如何给选中栏目添加特殊样式,一直没怎么搞清楚,今天学习了一下,并做个总结. 这边有两种情况,一种是直接给当前页面添加特殊样式,当网页刷新或者跳转到下一页后,样式消失:另一种情况是即使刷新页面后样式仍然有效. 直接上代码: 第一种情况: <script>   $(document).ready(function(){       $(".nav a").each(function(){           $(this).click(func