WPF觸控程序開發(二)——整理的一些問題


  上一篇(WPF觸控程序開發)介紹了幾個比較不錯的資源,比較基礎。等到自己真正使用它們時,問題就來了,現把我遇到的幾個問題羅列下,大家如有遇到其他問題或者有什么好的方法還望賜教。

  問題1.如何獲取觸控點的個數

  當你要在單指觸屏和多指觸屏時分別做不同的處理時就要用到。如何獲取,剛開始我是弄個List,在TouchDown時存儲輸入點,然后TouchUp時移除輸入點,這樣我要判斷輸入點的個數時只要獲取這個List的Count就行了,這是原始的做法,而且有的時候會不准(原因可能是down和up的事件拋出時機導致的,具體原因沒作研究),有個比較簡單的做法是在開頭引用一下 

using System.Linq ;

ManipulationStarting或者ManipulationDelta里可以使用

int deviceCount = e.Manipulators.Count();

來獲取即可。

  問題2.如何判斷觸控點是否位移

  這個問題也常遇到,情景是在單點抬起和單點移動再抬起做不同的處理,如單點抬起就彈窗,單點移動后抬起做翻頁,如何判斷呢?其實我上篇也略微提到了,就是定義一個TouchPoint類型的變量

TouchPoint touchPointOld;

TouchDown的時候

touchPointOld  = e.GetTouchPoint(this);

然后在TouchUp的時候獲取新點

TouchPoint touchPointNew = e.GetTouchPoint(this);

最后即可判斷X軸的位移

double offsetX = touchPointNew.Bounds.Left - touchPointOld.Bounds.Left ;//判斷X軸位移
  當然也可以判斷Y軸的位移。在這里多說一句,當我們在用鼠標模擬觸控測試時,是可以很精准地落下抬起,現實當中的手指落下抬起,雖然用戶主觀上沒有動,實際上可能會有5個像素左右的位移(手指是肉團,沒有鼠標那么精細),這時代碼就要判定超過5個像素的移動才算手指位移了。
 
  問題3.如何做精准的翻頁效果

  WPF的ScrollViewer已經支持觸屏了,設置PanningMode屬性即可滑動,但是這樣滑動是利用了慣性,想要控制精准翻頁比較困難。想做到像iphone相冊那樣的翻頁效果,即不管使用多大力氣,滑一次只翻一屏,這顯然不適用。目前我能想到的是用動畫來處理,大致思路是把羅列的對象放置於Canvas里(必須是Canvas,原因后面再說),然后使用DoubleAnimation作用於這個Canvas的TranslateTransform.XProperty,為避免生硬地滑動,可以設置DoubleAnimation的AccelerationRatio和DecelerationRatio,這樣能有加速和減速的效果。每次手指放下記錄點,抬起后判斷位移趨勢是左移還是右移,然后執行相應的動畫,當然,每次滑動多少就要自己計算了。

  上面說到了一定要使用Canvas,當然你也可以用Gird、StackPanel等等、不過你會發現,只要執行移動動畫,整個容器就會從你的視線消失。這可能與容器的特性有關,當你設置容器的寬度后(假設是水平滑動),執行動畫,改變TranslateTransform.XProperty,容器好像不是按照你的原來意思來滑動,而是把初始化的時候顯示的部分整體移動了,不管你設的寬度為多少,而Canvas則會像一張很長的畫布一樣慢慢展開。這個現象很容易重現,在blend里隨意試一下,設置容器轉換的X值(其實就是TranslateTransform.XProperty),你會很清晰得看到全過程。

  問題4.如何做圖片的平移、縮放、旋轉

  我認為這可以算觸控開發的進階了。因為這個涉及到操作一個原始的結構體——UI的Matrix。當然你想簡單做做的話直接用Blend自帶的TranslateZoomRotateBehavior就行,不過使用這個的話就相當於完全托管了,你能控制的東西很少。所以還是要直接操作Matrix。關於Matrix的介紹這里有個資源可以參考一下:WPF中的MatrixTransform

  不必研究很深入,你只需要知道Matrix有6個值,分別是M11,M12,M21,M22,OffsetX,OffsetY,其中M11和M22分別管的X軸和Y軸的縮放,OffsetX對應X軸位移,OffsetY對應Y軸位移,還有ScaleAt方法(縮放),Translate方法(平移),RotateAt方法(旋轉),看他們的傳入參數,基本都可以從e獲取,如ScaleAt方法需要四個參數:

public void ScaleAt (double scaleX, double scaleY , double centerX , double centerY );

一般做平移、旋轉、縮放的時候是寫在ManipulationDelta里面,前面兩個參數就可以從e的DeltaManipulation屬性獲得,為Scale.X和Scale.Y,后面兩個參數就更簡單了,是操作的中心點,也可以從e獲得,ManipulationOrigin屬性即為中心點,直接把他的X和Y傳入就行。

  還要多說一句,這里的Matrix改變后,並不影響UI的Width或者ActualWidth,如果想要獲取這類的值,需要計算。有這樣的情景,我需要在縮放到某個尺寸后就不讓繼續縮放了,這時候你去獲取UI的Width或者ActualWidth根本沒用,因為這些值一直沒變過。我的做法是定義全局變量,每次ManipulationDelta里改變的時候,就計算縮放后的新值,以此來記錄當前縮放狀態。其中ManipulationDelta的Scale.X就是X軸每次縮放的比例值。

  懂了這些,我認為已經算入門了。不過我也研究過iphone相冊的效果,它好像不是我這樣的思路。首先,它的滑動是實時跟隨的,當然我也可以做到那樣的效果;其次它的黑邊處理,是等寬填充,即不管相片多寬多高,寬度是始終充滿屏幕的,當你滑動時,不僅當前圖片跟隨移動,緊挨着的圖片也會受影響,而我的只是處理當前的對象,並未去影響其他的。這也可能是操作系統的區別吧,IOS沒研究過,說不定它是一個封好的控件,任何對象放進去就會有這樣的效果。我看了新浪、QQ的IOS客戶端,里面的圖片展示都是這樣的效果,看起來好容易。不過我相信,任何的效果都是代碼實現的,看起來越簡單,其實實現過程並不是那么簡單。IOS對我來說只是一個黑盒,我能模仿,甚至超越。


免責聲明!

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



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