UWP滑動后退


  經過近些年智能手機App的不斷發展,用戶已經不僅僅滿足於功能上的需求。UI、設計等非功能點逐漸在App體驗中占了大多數的分數。不知從何時起,滑動手勢就成為了App的一個標配。他不僅僅是一個功能,更是一個UI設計。其有以下幾個優點:

  1.方便了單手操作。在當今大屏手機占有率越來越高的趨勢下,簡潔方便的單手操作模式是很有必要的。

  2.美化了UI。你可能會有疑問,這是個功能,為什么美化了UI呢?其實,手勢操作的另一個利器就是隱藏了部分不是那么美觀的UI,使得界面看上去更簡。比如郵件App ,你如果要在界面上加入刪除、標記、已讀未讀等Button,那么界面會相當擁擠。

  3.讓用戶覺得你的App技術含量不是那么低。大多數用戶不懂技術,他們只看功能。如果別人有的東西你沒有,他們就會認為你的App技術含量過低。 

綜上所述,在你的App中加上滑動手勢非常有必要。

本文GitHub地址

一、手勢操作流程關鍵點

  手勢操作有三個關鍵狀態:操作開始時、操作進行時、操作結束時。

    1.操作開始時

在用戶開始手勢操作的那一刻,這時候主要進行一些初始化操作。  

    2.操作進行時

這時候不斷的計算用戶手勢相關的各種數據,方便后續處理。  

    3.操作結束時

這時候就是自由發揮了,你可以處理一些事件、功能。比如:頁面后退、顯示刪除按鈕等等 。

有一點需要注意:用戶可能並不是完全的水平或者豎直滑動,所以最好加上速度和位移長度雙重判斷處理。

二、實戰演示

在旺信UWP項目中,我們使用了滑動手勢來進行頁面的后退。下面我就以這個例子進行剖析。因為每個頁面都需要用到手勢,所以最好建一個BasePage類,然后讓所有頁面繼承這個類。

    1.相關事件添加

  在BasePage的構造函數中添加相關事件和手勢監聽的模式

private TranslateTransform _tt; 

 
this.ManipulationMode = ManipulationModes.TranslateX; 

this.ManipulationCompleted += BasePage_ManipulationCompleted; 

this.ManipulationDelta += BasePage_ManipulationDelta; 

_tt = this.RenderTransform as TranslateTransform; 

if (_tt == null) 
    this.RenderTransform = _tt = new TranslateTransform();

    2.手勢操作時的處理 

private void BasePage_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) 
 { 
    if (_tt.X + e.Delta.Translation.X < 0) 
     { 
         _tt.X = 0; 
        return; 
     } 
     _tt.X += e.Delta.Translation.X; 
 } 
    

    3.手勢結束時的操作

        private void BasePage_ManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
        {
                double abs_delta = Math.Abs(e.Cumulative.Translation.X);
                double speed = Math.Abs(e.Velocities.Linear.X);
                double delta = e.Cumulative.Translation.X;
                double to = 0;

                if (abs_delta < this.ActualWidth / 3 && speed < 0.5)
                {
                    _tt.X = 0;
                    return;
                }

                action = 0;
                if (delta > 0)
                    to = this.ActualWidth;
                else if (delta < 0)
                    return;

                var s = new Storyboard();
                var doubleanimation = new DoubleAnimation() { Duration = new Duration(TimeSpan.FromMilliseconds(120)), From = _tt.X, To = to };
                doubleanimation.Completed += Doubleanimation_Completed;
                Storyboard.SetTarget(doubleanimation, _tt);
                Storyboard.SetTargetProperty(doubleanimation, "X");
                s.Children.Add(doubleanimation);
                s.Begin();
            
        }

    4.結束后的動畫效果

     private void Doubleanimation_Completed(object sender, object e)
        {
            if (action == 0)
                //這里進行動畫結束后的操作,比如:頁面后退

            _tt = this.RenderTransform as TranslateTransform;
            if (_tt == null) this.RenderTransform = _tt = new TranslateTransform();
            _tt.X = 0;
        }

    這里為了視覺上的美觀,在手勢結束后增加了一段動畫效果。使頁面間的跳轉顯得不那么生硬。

三、一些需要注意的地方

有些控件自身帶有手勢功能,如:listview、scrollview等。這時候上邊自己添加的手勢事件就會被自動屏蔽掉。下邊是我個人的解決方案,如果你有更好的方法,歡迎一起討論。  

方案一:在DataTemplate上下手,加一個StackPanel,然后給他來個ManipulationMode="System,TranslateX"

    <ScrollViewer Grid.Row="1" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden">
            <StackPanel Orientation="Vertical" ManipulationMode="System,TranslateX" >
                <ItemsControl x:Name="control_blacklist" ItemsSource="{Binding BlackList}" Grid.Row="1">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Vertical" ManipulationMode="System,TranslateX" >
                                <mine:MineBlackListControl Background="White"></mine:MineBlackListControl>
                                <Line X1="1" Style="{StaticResource WXLineStyle}" VerticalAlignment="Bottom" />
                            </StackPanel>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
        </ScrollViewer>

 

  方案二:這種方式和上邊那種一樣,只不過是統一處理了

    <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Vertical" Background="Transparent" ManipulationMode="System,TranslateX"/>
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM