UWP中使用Composition API實現吸頂(1)

来源:http://www.cnblogs.com/blue-fire/archive/2017/06/12/6991097.html
-Advertisement-
Play Games

前幾天需要在UWP中實現吸頂,就在網上找了一些文章: 吸頂大法 -- UWP中的工具欄吸頂的實現方式之一 在UWP中頁面滑動導航欄置頂 發現前人的實現方式大多是控制ListViewBase的Header變換高度,或者建立一個ScrollViewer在裡面放置ListViewBase。經過測試,這兩種 ...


前幾天需要在UWP中實現吸頂,就在網上找了一些文章:

吸頂大法 -- UWP中的工具欄吸頂的實現方式之一

在UWP中頁面滑動導航欄置頂

發現前人的實現方式大多是控制ListViewBase的Header變換高度,或者建立一個ScrollViewer在裡面放置ListViewBase。經過測試,這兩種方法或多或少的都有問題。所以我想試試用Composition API實現吸頂的效果。

首先先瞭解一下Composition API是什麼。

Windows.UI.Composition 是可以從任何通用 Windows 平臺 (UWP) 應用程式調用的聲明性保留模式 API ,從而可以直接在應用程式中創建合成對象、 動畫和效果。 該 API 是對諸如 XAML 等現有框架的一個強大補充,從而為 UWP 應用程式開發人員提供了一個熟悉的 C# 圖面以供添加到其應用程式。 這些 API 還可以用於創建 DX 樣式框架較少的應用程式。

XAML 開發人員可以使用 WinRT“下拉”到採用 C# 的合成層,以便在該合成層上執行自定義工作,而無需一直下拉到圖形層並針對任何自定義 UI 工作使用 DirectX 和 C++。 此技術可用於使用合成 API 對現有元素進行動畫處理,也可用於通過在 XAML 元素樹內創建 Windows.UI.Composition 內容的“視覺島”來增加 UI。

只看這幾句微軟給的介紹也是雲里來霧裡去的,還是看代碼吧。

CompositionAPI中有一種動畫叫表達式動畫。大致效果就是讓一個Visual或者PropertySet的屬性隨著自身另一個屬性,或者另一個Visual或者PropertySet的屬性的變化而變化。

對於不含Pivot的簡單情況,就有這樣一個基本的思路了:

  1. 獲取到ListViewBase的ScrollViewer;
  2. 獲取到ScrollViewer的ManipulationPropertySet和ListViewHeader的Visual;
  3. 讓ManipulationPropertySet和Visual發生關係。

我們先來建立一個簡單的頁面。

<Page
    x:Class="TestSwipeBack.ScrollTest"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:TestSwipeBack"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" Loaded="Page_Loaded">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <ListView x:Name="_listview" ItemsSource="{x:Bind ItemSource,Mode=OneWay}">
            <ListView.Header>
                <Grid x:Name="_header">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="100" />
                        <RowDefinition Height="50" />
                    </Grid.RowDefinitions>
                    <Grid Background="LightBlue">
                        <Button>123</Button>
                        <TextBlock FontSize="25" HorizontalAlignment="Center" VerticalAlignment="Center">我會被隱藏</TextBlock>
                    </Grid>
                    <Grid Background="Pink" Grid.Row="1">
                        <Button>123</Button>
                        <TextBlock FontSize="25" HorizontalAlignment="Center" VerticalAlignment="Center">我會吸頂</TextBlock>
                    </Grid>
                </Grid>
            </ListView.Header>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding }" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>

原本ListViewBase里Header是在ItemsPanelRoot下方的,使用Canvans.SetZIndex把ItemsPanelRoot設置到下方。

Canvas.SetZIndex(_listview.ItemsPanelRoot, -1);

然後在後臺獲取ListView內的ScrollViewer。

var _scrollviewer = FindFirstChild<ScrollViewer>(_listview);

static T FindFirstChild<T>(FrameworkElement element) where T : FrameworkElement
{
int childrenCount = VisualTreeHelper.GetChildrenCount(element);
    var children = new FrameworkElement[childrenCount];

for (int i = 0; i < childrenCount; i++) { var child = VisualTreeHelper.GetChild(element, i) as FrameworkElement; children[i] = child; if (child is T) return (T)child;
}
for (int i = 0; i < childrenCount; i++) if (children[i] != null) { var subChild = FindFirstChild<T>(children[i]); if (subChild != null) return subChild; } return null;
}

獲取ListViewHeader的Visual和ScrollViewer的ManipulationPropertySet。

var _headerVisual = ElementCompositionPreview.GetElementVisual(_header);
var _manipulationPropertySet = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(_scrollviewer);

創建表達式動畫,然後運行。

var _compositor = Window.Current.Compositor;
var _headerAnimation = _compositor.CreateExpressionAnimation("_manipulationPropertySet.Translation.Y > -100f ? 0: -100f -_manipulationPropertySet.Translation.Y");
//_manipulationPropertySet.Translation.Y是ScrollViewer滾動的數值,手指向上移動的時候,也就是可視部分向下移動的時候,Translation.Y是負數。

_headerAnimation.SetReferenceParameter("_manipulationPropertySet", _manipulationPropertySet);

_headerVisual.StartAnimation("Offset.Y", _headerAnimation);

 

現在滑動Demo看看,是不是在滾動100像素之後,Header就停住了?

 

註:在一個Visual或者propertySet被附加了動畫(即StartAnimation或者StartAnimationGroup)之後,取出(propertySet.TryGetScalar)相應的屬性就只能取到0,但是賦值或者插入數值是會生效的。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 代碼格式化:Ctrl K +Ctrl D ...
  • 寫在前面整個項目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp善用 Ctrl + F 查找題目。本節你可能會需要的兩個測試數據文件:largeW: http://algs4.cs.princeto... ...
  • ServerSuperIO以前所做的工作逐步為形成迴路控制或級聯控制打下基礎,例如:服務連接器和設備驅動連接器的開發與應用。總之,是通過多種形式下發命令控制設備(驅動)或感測器,雲端控制站點或監測點的感測器、App或者其他終端控制感測器、根據感測器的採集數據控制另一個感測器等。 ...
  • 現在辦公要流程化,營銷也有流程,流程現在已經是各種生活活動不可缺少的一部分了。就像這句耳熟能詳的話:“凡事,我們先走個流程嘛!”,在信息化、流程化的背景下。工作流引擎,這個名詞就出現了!那麼,什麼是工作流引擎呢?所謂工作流引擎是指workflow作為應用系統的一部分,併為之提供對各應用系統有決定作用 ...
  • 前段時間巨硬發佈了一款新的輸入設備Surface Dial,配合Surface Studio使用簡直炫酷到沒朋友。 本人由於公司業務有幸參與了微軟的相關培訓,最大的收穫覺得是發現WPF居然也可以開發Dial, WPF居然可以使用UWP的API! 不賣關子,關鍵就是名為“UwpDesktop”的一個N ...
  • Object中的公共方法解釋: 公共方法: Equals: public class Object { public virtual Boolean Equals(Object obj) { //如果兩個引用指向同一個對象,他們肯定包含相同的值 if (this == obj) return tru ...
  • 由於種種原因吧,我需要使用一個WPF程式起調一個UWP程式,下麵總結一下,給自己個備份。 啟動UWP程式的關鍵是協議啟動 給我們的UWP應用添加一個協議,like this: 然後使用協議啟動該UWP有一下幾種方式: 1. 使用UWP的Launcher API // Create the URI t ...
  • 背水一戰 Windows 10 之 控制項(集合類 - ItemsControl): 自定義 ItemsControl(自定義 GirdView 使其每個 item 占用不同大小的空間), 自定義 ContentPresenter 實現類似 GridViewItemPresenter 和 ListVi... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...