Fork me on GitHub

UWP 模仿NetFlix首页效果

English version see How to made a NetFlix alike app using UWP?

 

之前写过UWP 带左右滚动按钮的横向ListView———仿NetFlix首页河的设计,讲述了如何设计一个带有左右滚动按钮横向的ListView

不过我在半年之前挖了一个坑,由于工作关系,没时间来填坑。这篇文章也是花了好几天时间零零散散写的。

 

要是完全实现仿照NetFlix首页那样,我们还需要一个竖向的重复排列的控件。【什么???NetFlix是什么???一个世界顶级视频网站,相比之下优酷腾讯爱奇艺都是渣渣的那种】

说到这,大家肯定首先想到了ListView

没错,我一开始也确实用来ListView,然后再它的DataTemplate里面用了之前那篇文章的控件。

复制代码
<Page.Resources>
   <DataTemplate x:Key="riverTemplate" x:DataType="local:Product">
      <StackPanel>
         <Image Width="200" Height="200" Source="{x:Bind image}"/>
         <TextBlock Text="{x:Bind text}" Margin="0 10 0 0" FontSize="18"/>
      </StackPanel>
   </DataTemplate>
</Page.Resources>

<ListView x:Name="listView">
   <ListView.ItemTemplate>
      <DataTemplate x:DataType="local:StoreModel">
         <StackPanel Margin="0 0 0 32">
         <TextBlock Text="{x:Bind title}" FontSize="28"/>
         <local:StepThroughListView
            Margin="0 10 0 0"
            AlwaysShowButton="Collapsed"
            ItemsSource="{x:Bind products}"
            ItemTemplate="{StaticResource riverTemplate}"/>
         </StackPanel>
      </DataTemplate>
   </ListView.ItemTemplate>
</ListView>
复制代码

 

 

上面的代码会产生下面的类似效果图:

 

 

 

在这之前,先说明一下,NetFlix的首页上下滚动,数据非常多,而且不卡的。

使用了ListView承载的话,它会启动内部的虚拟化机制,不渲染没有在视野的Items,减少App的CPU和内存消耗。

 

但是!!!

有一个非常大的bug就是,在实际的项目中,数据模板设计会有比较多的元素展示。当用鼠标快速上下拖动滚动条的时候,整个App就是一片空白,控件渲染速度明显跟不上了。

还有就是在XBox上也是一样,更慢。。。

 

 

所以为了优化ListView,微软在Windows UI Library项目中又新推出了一个船新的ItemsRepeater控件。

ItemsRepeater,从字面的意思上就可以猜出大概,它只是完成一些重复的项,并且它没有UI。

通过 ItemsRepeater 创建使用灵活布局系统、自定义视图和虚拟化的自定义集合体验。
与 ListView 不同,ItemsRepeater 不提供综合性的最终用户体验 - 它没有没有默认 UI,不提供任何围绕焦点、选择或用户交互的策略, 
而是一个构建基块,你可以使用它来创建自己的基于集合的独特体验和自定义控件。 虽然它没有内置的策略,但允许你附加策略来构建所需的体验。 例如,你可以定义要使用的布局、键盘操作策略、选择策略等。
在概念上,可以将 ItemsRepeater 视为数据驱动的面板,而不是 ListView 之类的完整控件。 

 

 

由此可以看出,ItemsRepeater好像是吸取了Flutter的精髓,万物皆是Widget的思想。其实如果之前所有的UWP控件都要是围绕这种思想的话,UWP也不至于沦落至此。

既然ItemsRepeater是一个基块,那么我们就可以像搭积木一样,把它放进如何现有的控件中。

没有UI和交互的代码逻辑,从而可以实现更为高效的布局,这使得ItemsRepeater在最终用户体验上比ListView,特别是在中低端机器上,更为优秀。

 

那么,到这里大家就清楚了,要实现一个类似NetFLix的效果,我们需要一个纵向的ItemsRepeater,每一个ItemsRepeater需要包含一个横向的ItemsRepeater

 

1. 通过ItemsRepeater进行滚动

ItemsRepeater 不是派生自控件,因此没有控件模板。 因此,它不包含任何内置的滚动功能,这一点不同于 ListView 或其他集合控件。
使用 ItemsRepeater 时,若要提供滚动功能,则应将其包装在 ScrollViewer 控件中。

通过查看ItemsRepeater的元数据也可以看到。

 

 

如果应用会在较早的 Windows 版本(在 Windows 10 版本 1809 之前发行的版本)上运行,则还需将 ScrollViewer 托管在 ItemsRepeaterScrollHost 中。

 

<muxc:ItemsRepeaterScrollHost>
    <ScrollViewer>
        <muxc:ItemsRepeater ... />
    </ScrollViewer>
</muxc:ItemsRepeaterScrollHost>

 

 

2. 定义数据模板

首先从小到大,先分解一下水平的列表,定义成一个Horizontal Template

一张电视剧封面图,下面放一个对图片的描述,比如电视剧名称,分类等

复制代码
        <!--Horizontal ItemsRepeater data template-->
        <DataTemplate x:Key="HorizontalTemplate" x:DataType="local:Product">
            <StackPanel>
                <Image 
                    Source="{x:Bind image}"/>
                <TextBlock 
                    Margin="0 12 0 0"
                    Text="{x:Bind text}"/>
            </StackPanel>
        </DataTemplate>
复制代码

 

 

然后整个纵向的列表,定义一个Vertical Template

一个标题分类,加上这个分类下的一些电视剧。

复制代码
        <!--Vertical ItemsRepeater data template-->
        <DataTemplate x:Key="VerticalTemplate" x:DataType="local:StoreModel">
            <StackPanel>
                <TextBlock 
                    FontSize="36"
                    Text="{x:Bind title}"/>
                <muxc:ItemsRepeaterScrollHost>
                    <ScrollViewer HorizontalScrollMode="Enabled" HorizontalScrollBarVisibility="Visible">
                        <muxc:ItemsRepeater 
                            Margin="0 20 0 0" 
                            ItemsSource="{x:Bind products}"
                            ItemTemplate="{StaticResource HorizontalTemplate}">
                            <muxc:ItemsRepeater.Layout>
                                <muxc:StackLayout Orientation="Horizontal" Spacing="20"/>
                            </muxc:ItemsRepeater.Layout>
                        </muxc:ItemsRepeater>
                    </ScrollViewer>
                </muxc:ItemsRepeaterScrollHost>
            </StackPanel>
        </DataTemplate>
复制代码

 

 

大体的模型如下

 

3. 开始写界面

就像一开始所说的那样,最好在ScrollViewer外面加上一个ScrollHost,这样比较保险一点。 

复制代码
    <muxc:ItemsRepeaterScrollHost>
        <ScrollViewer>
            <muxc:ItemsRepeater
                x:Name="NetFlixItemsRepeater"
                ItemTemplate="{StaticResource VerticalTemplate}">
                <muxc:ItemsRepeater.Layout>
                    <muxc:StackLayout Orientation="Vertical" Spacing="40"/>
                </muxc:ItemsRepeater.Layout>
            </muxc:ItemsRepeater>
        </ScrollViewer>
    </muxc:ItemsRepeaterScrollHost>
复制代码

 

 

需要注意的是,在ItemsRepeater的布局里面,需要指定它的方向。默认是纵向的。

像刚才在横向的模板里面,我就特别指定它的方向是横向。

 

4. 编写测试数据,进行压力测试

我直接在Page_Laded里加了数据,简单粗暴。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private void Page_Loaded(object sender, RoutedEventArgs e)
{
    List<Product> products = new List<Product>();
    for (int i = 0; i < 100; i++)
    {
        products.Add(
            new Product {
            text = i.ToString(),
            image = "ms-appx:///Assets/v2.jpg"
            }
            ) ;
    }
 
    for (int i = 0; i < 100; i++)
    {
        stores.Add(
            new StoreModel
            {
                title = "River" + i.ToString(),
                products = products
            }
            );
    }
 
    //listView.ItemsSource = stores;
    NetFlixItemsRepeater.ItemsSource = stores;
}

  

 

5. 运行App测试,看内存和CPU

 

 

 

 

 

视频链接:https://youtu.be/2qqYywttue4

 

也欢迎大家订阅我的Youtube频道,谢谢!

 

点击右下角红色小铃铛🔔,第一时间获取最新信息。

 

 

 

本项目已开源,项目地址:https://github.com/hupo376787/NetFlix_UWP

也欢迎Star一下我的项目。谢谢。

 

posted @   猫叔Vincent  阅读(2046)  评论(5编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2018-04-20 一个汉字占多少字节?
2018-04-20 UWP 剪贴板 Clipboard
2018-04-20 UWP 取消GridView、ListView鼠标选中、悬停效果
2018-04-20 UWP 响应键盘组合快捷键
点击右上角即可分享
微信分享提示