2015-10-27 46 views
0

我目前正在開發Xamarin.Forms的SideDrawer,因爲在這一點上,來自telerik的一個是相當糟糕的sideeffect明智的。如何使Xamarin氣泡手勢

我知道如何在WPF中做到這一點,因爲它很容易,但在Xamarin中它有不同的方式。

我的GestureFrame代碼與this幾乎相同。

我使用的源碼爲some github project/xamarin docs/XLabs以開始使用。起初它運轉良好,但只要我將控件放置在手勢框內,我就不會再收到任何事件,因爲childcontrols似乎消耗了任何觸摸/手勢事件。

這是否對任何人敲響?現在,我不知道我可能會做什麼錯誤的控制行爲這種方式

+0

哪個平臺? – Cheesebaron

+0

@Cheesebaron Xamarin.Forms。現在增加它的問題。謝謝 – Dbl

回答

1

Xamarin形式處理當前的唯一手勢是Tap和DoubleTap默認這些泡沫。對於Android來說,Windows和大概IOS都會以不同的方式處理其他手勢。

快速回顧事件的Xamarin.Forms世界處理的:

在Android 手勢被渲染的每個渲染器的觸摸事件進行處理。當手勢發生時,觸摸在渲染器中引發。通過訂閱Touch事件並添加EventArgs,您可以確定屏幕上發生了什麼。現在,您可以自己做出關於用戶正在做什麼的所有決定,或者使用Mono.Android.GestureDetector爲您做出這些決定。 GestureDetector需要一個GestureListener,它在它認爲發生了像tap或double這樣的事件時通知它。然後你的手勢監聽器可以包含你想要響應這些事件的任何代碼。

在Windows 每個本地控制決定爲自己當發生一個事件,並公開了一組事件處理這些事件。要響應這些事件,您需要創建一個自定義渲染器並訂閱本機控件上的事件,然後執行您自己的代碼。

關於IOS? 不知道還有沒有在我的項目中得到那麼多https://github.com/Indiponics/IndiXam-Lib也許別人可以給你那一塊。

冒泡事件 讓我們來看一個簡單的起泡情況:

public class App : Application 
{ 
    public App() 
    { 
     // The root page of your application 
     MainPage = new ContentPage 
     { 
      Content = new Frame 
      { 
       Content = 
        new Label { 
         Text = "Hold Me, Thrill Me, Kiss Me" 
        } 
      } 
     }; 
    } 
} 

讓我們把一些自定義渲染在一起,看看發生了什麼。首先,我們需要一個渲染器來處理堆棧中的每個控件,所以在我們的例子中是一個標籤渲染器和一個幀渲染器。

我們將在Windows啓動:

[assembly: ExportRenderer(typeof(Label), typeof(myLabelCustomRenderer))] 
[assembly: ExportRenderer(typeof(Frame), typeof(myFrameCustomRenderer))] 
namespace App4.WinPhone 
{ 
    public class myFrameCustomRenderer:FrameRenderer 
    { 
     protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Frame> e) 
     { 
      base.OnElementChanged(e); 
      if(e.NewElement!=null) 
      { 
       this.Control.Hold += Control_Hold; 
      } 
     } 

     void Control_Hold(object sender, System.Windows.Input.GestureEventArgs e) 
     { 
      System.Diagnostics.Debug.WriteLine("Frame Held"); 
      e.Handled = false; 
     } 
    } 
    public class myLabelCustomRenderer : LabelRenderer 
    { 
     protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Label> e) 
     { 
      base.OnElementChanged(e); 
      if (e.NewElement != null) 
      { 
       this.Control.Hold += Control_Hold; 
      } 
     } 

     void Control_Hold(object sender, System.Windows.Input.GestureEventArgs e) 
     { 
      System.Diagnostics.Debug.WriteLine("Label Held"); 
      e.Handled = false; 
     } 
    } 
} 

運行此我們發現 鼓泡實際上默認Windows發生。如果我們想我們可以關閉通過改變

e.Handled = true; 

在我們的標籤渲染起泡和框架絕不會通知按住事件。

現在For Android 在Android上,事情變得有點混亂。我們再次創建兩個渲染器。

[assembly: ExportRenderer(typeof(Label), typeof(myLabelCustomRenderer))] 
[assembly: ExportRenderer(typeof(Frame), typeof(myFrameCustomRenderer))] 
namespace App4.Droid 
{ 
    public class myFrameCustomRenderer : FrameRenderer 
    { 
     protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Frame> e) 
     { 
      base.OnElementChanged(e); 
      if (e.NewElement != null) 
      { 
       this.Touch += myFrameCustomRenderer_Touch; 
      } 
     } 

     void myFrameCustomRenderer_Touch(object sender, Android.Views.View.TouchEventArgs e) 
     { 
      System.Diagnostics.Debug.WriteLine("You Touched My Frame"); 
      e.Handled = false; 
     } 
    } 
    public class myLabelCustomRenderer : LabelRenderer 
    { 
     protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Label> e) 
     { 
      base.OnElementChanged(e); 
      if (e.NewElement != null) 
      { 
       this.Touch += myFrameCustomRenderer_Touch; 
      } 
     } 

     void myFrameCustomRenderer_Touch(object sender, Android.Views.View.TouchEventArgs e) 
     { 
      System.Diagnostics.Debug.WriteLine("You Touched My Label"); 
      e.Handled = false; 
     } 
    } 
} 

如果我們運行這個看起來一切正常一樣的窗戶,我們木屐在標籤觸摸事件,並在框架中的觸摸事件。冒泡似乎是自動的。當我們嘗試禁用冒泡時它變得雜亂。如果我們改變

e.Handled = true;

在標籤渲染器中,並再次運行該應用程序--- 在LABEL RENDERER中觸摸兩次。一次當我們觸摸屏幕時,一次當我們停下來時。如果我們設置labelrenderer的e.Handled = false;並將Frame設置爲true。然後,標籤觸發隨後的框架,但只有框架第二次觸發。

另外,如果我們從渲染器中刪除e.Handled = false並運行應用程序,我們會發現只有LabelRenderer的Touch事件觸發。暗示Handled的默認值是正確的。如果您在渲染器中未設置e.Handled = false,則該事件將在LabelRenderer中觸發,而不會將堆棧向上渲染到FrameRenderer。

結論: Bubbling在Windows上開箱即用。在Android上,它不會像你所期望的那樣工作。首先,你必須在每個孩子中明確地設置Handled = false,這樣父母才能得到通知,即使只有處理事件的Handler得到通知,觸摸事件結束了堆棧的其餘部分纔會得到啓動的通知,但從來不知道它的結束。