Fork me on GitHub

How to made a NetFlix alike app using UWP?

中文版请参考:UWP 模仿NetFlix首页效果

 

 

Long time ago, I wrote an article about how to made a horizontal listview with left/right scroll buttons.

But I mentioned sometimes later, I will write a NetFlix alike app. Due to work, I don't have enough time to do it. This article also took me several days to finish.

 

So in order to write a page like NetFLix home page, we need to user a vertical control with repeated items.

Speaking of this, you must think it's ListView.

Yeah, right. I did use ListView at first, and use my previous custom control in it's 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>

 

 

 

The above code will render a UI like:

 

 

 

 

 Before doing this, I must declare that NetFlix's hoe page is very smooth while scrolling up and down quickly.

If you use ListView, it will use internal visualization, which doesn't render items that not exist in current view port, this can reduce cpu and memory usage.

 

BUT,

There exist a bug in ListView, in our production project, we will use much more elements in item data template. So, when you scrolling up and down very quickly, the view port will become blank.

This bug also exists on XBox, much more slower...

 

 

So, in order to improve the performance of ListView, Microsoft released a totally new control ItemsRepeater in their open source project: Windows UI Library.

ItemsRepeater, from the word meaning, is about doing things to complete repeate items. One more thing, ItemsRepeater doesn't have user interface.

Use an ItemsRepeater to create custom displays for collections of data. While it can be used to present a basic set of items, you might often use it as the display element in the template of a custom control.

ItemsRepeater does not have a built-in Items collection. If you need to provide an Items collection directly, rather than binding to a separate data source, then you're likely in need of a more high-policy experience and should use ListView or GridView.

ItemsControl and ItemsRepeater both enable customizable collection experiences, but ItemsRepeater supports virtualizing UI layouts, while ItemsControl does not. We recommend using ItemsRepeater instead of ItemsControl, whether its for just presenting a few items from data or building a custom collection control.

 

 

So, from the passage, we can see that ImtesRepeater have absorbed the core value of Flutter, everything is widget.

If Microsoft realized this core value at the beginning, UWP will not be nearly dead now.

Since ItemsRepeater is a base set, then we can put in current controls like building blocks.

Without UI and interaction logic, ItemsRepeater can access more flexable layout. It also behaves more elegent on lower machines than ListView for our end user experience.

 

Until now, we are clear that if we want to build a NetFlix alike app, we need a vertical ItemsRepeater list, each ItemsRepeater need to contains a horizontal ItemsRepeater.

 

 

1. Scroll using ItemsRepeater

ItemsRepeater does not derive from Control, so it doesn't have a control template. Therefore, it doesn't contain any built-in scrolling like a ListView or other collection controls do.
When you use an ItemsRepeater, you should provide scrolling functionality by wrapping it in a ScrollViewer control.

We can also view ItemsRepeater's metadata.

 

 If your app will run on earlier versions of Windows - those released before Windows 10, version 1809 - then you also need to host the ScrollViewer inside the ItemsRepeaterScrollHost.

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

 

 

 

2. Customize data template

From small to large, we nned to analysis the horizontal ItemsRepeater's template, we set it's key to "HorizontalTemplate".

Each card contains a series cover, and a series name, series category, etc.

        <!--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>

 This piece of code will generate items like below.

 

Then the whole vertical list, we customize a vertical template: a category name and a Horizontal ItemsRepeater.

        <!--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>

This piece of code will generate like below.

 

3. Write xaml ui

As is just said at the beginning, in a more safe way, we wolud better use a ScrollHost outside of ScrollViewer

    <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>

 

 Pay attention to ItemsRepeater's orientation. By dedault, it's vertical.

I set it to horizontal in the horizontal data template.

 

4. Create a data collection, and test

I just create 100 rows, each row contains 100 items in Page_Loaded event.

At the end of code, specify the Items source to your collection.

        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. Build, run and watch CPU/Memory useage

 

 

 

 

 

I uploaded a video to Youtube: https://youtu.be/2qqYywttue4

 

And welcome to subscrible my Youtube Channel.

Click the red bell at the bottom-right corner🔔, you can get the latest information at first time. 

 

 

 

 

This project is open source, see Github https://github.com/hupo376787/NetFlix_UWP

Welcome star, thanks.

 

posted @ 2020-04-21 11:25  猫叔Vincent  阅读(554)  评论(0编辑  收藏  举报