2016-08-06 10 views
8

ich zu meinem Ereignisse auslösen soll, wenn die Taste gedrückt und freigegeben, aber ich kann nur Click Ereignis in Xamarin.Forms finden.Xamarin.Forms - Taste gedrückt und freigegeben Ereignis

Ich glaube, es muss etwas Arbeit um diese Funktionalität zu bekommen. Mein Grundbedürfnis ist, einen Prozess zu starten, wenn Knopf gedrückt wird und zu stoppen, wenn er freigegeben wird. Es scheint eine sehr grundlegende Funktion zu sein, aber Xamarin.Forms hat es gerade nicht.

Ich versuchte TapGestureRecognizer auf Knopf, aber Knopf feuert nur Klickereignis ab.

MyButton.Clicked += (sender, args) => 
{ 
    Log.V(TAG, "CLICKED"); 
}; 

var tapGestureRecognizer = new TapGestureRecognizer(); 
tapGestureRecognizer.Tapped += (s, e) => { 
    Log.V(TAG, "TAPPED"); 
}; 
MyButton.GestureRecognizers.Add(tapGestureRecognizer); 

Denken Sie daran, dass ich diese Ereignisse in Android und iOS zu arbeiten benötigen.

+0

Sie müssten eine benutzerdefinierte Schaltfläche Renderer schreiben, die die zugrunde liegende TouchDown- und TouchUp aussetzt Ereignisse, die Masken bilden. – Jason

+0

@jason können Sie mir ein gutes Tutorial oder ein Beispiel für einen benutzerdefinierten Renderer vorschlagen ... ??? –

+0

https://developer.xamarin.com/guides/xamarin-forms/custom-renderer/ – Jason

Antwort

17

Endlich bekam ich die von @Jason vorgeschlagene Lösung. Hier gehen wir ...

  1. erstellen Unterklasse von Xamarin.Forms.Button in PCL-Projekt, mit Ereignis Handhabungsfähigkeit

    public class CustomButton : Button 
    { 
        public event EventHandler Pressed; 
        public event EventHandler Released; 
    
        public virtual void OnPressed() 
        { 
         Pressed?.Invoke(this, EventArgs.Empty); 
        } 
    
        public virtual void OnReleased() 
        { 
         Released?.Invoke(this, EventArgs.Empty); 
        } 
    } 
    
  2. Erstellen plattformspezifische Schaltfläche Renderer in jeweiligen Projekt

    Für Andorid

    [assembly: ExportRenderer(typeof(Button), typeof(CustomButtonRenderer))] 
    namespace WalkieTalkie.Droid.Renderer 
    { 
        public class CustomButtonRenderer : ButtonRenderer 
        { 
         protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e) 
         { 
          base.OnElementChanged(e); 
    
          var customButton = e.NewElement as CustomButton; 
    
          var thisButton = Control as Android.Widget.Button; 
          thisButton.Touch += (object sender, TouchEventArgs args) => 
          { 
           if (args.Event.Action == MotionEventActions.Down) 
           { 
            customButton.OnPressed(); 
           } 
           else if (args.Event.Action == MotionEventActions.Up) 
           { 
            customButton.OnReleased(); 
           } 
          }; 
         } 
        } 
    } 
    

    Für IOS

    [assembly: ExportRenderer(typeof(CustomButton), typeof(CustomButtonRenderer))] 
    namespace WalkieTalkie.iOS.Renderer 
    { 
        public class CustomButtonRenderer : ButtonRenderer 
        { 
         protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e) 
         { 
          base.OnElementChanged(e); 
    
          var customButton = e.NewElement as CustomButton; 
    
          var thisButton = Control as UIButton; 
          thisButton.TouchDown += delegate 
          { 
           customButton.OnPressed(); 
          }; 
          thisButton.TouchUpInside += delegate 
          { 
           customButton.OnReleased(); 
          }; 
         } 
        } 
    } 
    
  3. Instantiate Ihre benutzerdefinierte Schaltfläche auf Ihrer Seite

    var myButton = new CustomButton 
    { 
        Text = "CustomButton", 
        HorizontalOptions = LayoutOptions.FillAndExpand 
    }; 
    myButton.Pressed += (sender, args) => 
    { 
        System.Diagnostics.Debug.WriteLine("Pressed"); 
    }; 
    myButton.Released += (sender, args) => 
    { 
        System.Diagnostics.Debug.WriteLine("Pressed"); 
    }; 
    

Hope this jemand helfen :)

+1

Es hat jemandem geholfen :) –

2
Button button = FindViewById (Resource.Id.myButton); 
button.Touch += (object sender, View.TouchEventArgs e) => 
{ 
if (e.Event.Action == MotionEventActions.Up) 
{ 
Toast.MakeText(this, "Key Up", ToastLength.Short).Show(); 
} 
     if(e.Event.Action == MotionEventActions.Down) 
     { 
      Toast.MakeText(this, "Key Down", ToastLength.Short).Show(); 
     } 
    }; 
6

Dies kann auch mit einem Effekt anstelle eines getan werden vollwertiger Custom Renderer.Sehen Sie diesen Beitrag für eine Erklärung, wie es zu tun:

https://alexdunn.org/2017/12/27/xamarin-tip-xamarin-forms-long-press-effect/

Falls das jemals geht weg zu veröffentlichen, hier ist der Code, den Sie implementieren können:

Im gemeinsamen Projekt:

/// <summary> 
/// Long pressed effect. Used for invoking commands on long press detection cross platform 
/// </summary> 
public class LongPressedEffect : RoutingEffect 
{ 
    public LongPressedEffect() : base("MyApp.LongPressedEffect") 
    { 
    } 

    public static readonly BindableProperty CommandProperty = BindableProperty.CreateAttached("Command", typeof(ICommand), typeof(LongPressedEffect), (object)null); 
    public static ICommand GetCommand(BindableObject view) 
    { 
     return (ICommand)view.GetValue(CommandProperty); 
    } 

    public static void SetCommand(BindableObject view, ICommand value) 
    { 
     view.SetValue(CommandProperty, value); 
    } 


    public static readonly BindableProperty CommandParameterProperty = BindableProperty.CreateAttached("CommandParameter", typeof(object), typeof(LongPressedEffect), (object)null); 
    public static object GetCommandParameter(BindableObject view) 
    { 
     return view.GetValue(CommandParameterProperty); 
    } 

    public static void SetCommandParameter(BindableObject view, object value) 
    { 
     view.SetValue(CommandParameterProperty, value); 
    } 
} 

In Android:

[assembly: ResolutionGroupName("MyApp")] 
[assembly: ExportEffect(typeof(AndroidLongPressedEffect), "LongPressedEffect")] 
namespace AndroidAppNamespace.Effects 
{ 
    /// <summary> 
    /// Android long pressed effect. 
    /// </summary> 
    public class AndroidLongPressedEffect : PlatformEffect 
    { 
     private bool _attached; 

     /// <summary> 
     /// Initializer to avoid linking out 
     /// </summary> 
     public static void Initialize() { } 

     /// <summary> 
     /// Initializes a new instance of the 
     /// <see cref="T:Yukon.Application.AndroidComponents.Effects.AndroidLongPressedEffect"/> class. 
     /// Empty constructor required for the odd Xamarin.Forms reflection constructor search 
     /// </summary> 
     public AndroidLongPressedEffect() 
     { 
     } 

     /// <summary> 
     /// Apply the handler 
     /// </summary> 
     protected override void OnAttached() 
     { 
      //because an effect can be detached immediately after attached (happens in listview), only attach the handler one time. 
      if (!_attached) 
      { 
       if (Control != null) 
       { 
        Control.LongClickable = true; 
        Control.LongClick += Control_LongClick; 
       } 
       else 
       { 
        Container.LongClickable = true; 
        Container.LongClick += Control_LongClick; 
       } 
       _attached = true; 
      } 
     } 

     /// <summary> 
     /// Invoke the command if there is one 
     /// </summary> 
     /// <param name="sender">Sender.</param> 
     /// <param name="e">E.</param> 
     private void Control_LongClick(object sender, Android.Views.View.LongClickEventArgs e) 
     { 
      Console.WriteLine("Invoking long click command"); 
      var command = LongPressedEffect.GetCommand(Element); 
      command?.Execute(LongPressedEffect.GetCommandParameter(Element)); 
     } 

     /// <summary> 
     /// Clean the event handler on detach 
     /// </summary> 
     protected override void OnDetached() 
     { 
      if (_attached) 
      { 
       if (Control != null) 
       { 
        Control.LongClickable = true; 
        Control.LongClick -= Control_LongClick; 
       } 
       else 
       { 
        Container.LongClickable = true; 
        Container.LongClick -= Control_LongClick; 
       } 
       _attached = false; 
      } 
     } 
    } 
} 

In iOS:

[assembly: ResolutionGroupName("MyApp")] 
[assembly: ExportEffect(typeof(iOSLongPressedEffect), "LongPressedEffect")] 
namespace iOSNamespace.Effects 
{ 
    /// <summary> 
    /// iOS long pressed effect 
    /// </summary> 
    public class iOSLongPressedEffect : PlatformEffect 
    { 
     private bool _attached; 
     private readonly UILongPressGestureRecognizer _longPressRecognizer; 
     /// <summary> 
     /// Initializes a new instance of the 
     /// <see cref="T:Yukon.Application.iOSComponents.Effects.iOSLongPressedEffect"/> class. 
     /// </summary> 
     public iOSLongPressedEffect() 
     { 
      _longPressRecognizer = new UILongPressGestureRecognizer(HandleLongClick); 
     } 

     /// <summary> 
     /// Apply the handler 
     /// </summary> 
     protected override void OnAttached() 
     { 
      //because an effect can be detached immediately after attached (happens in listview), only attach the handler one time 
      if (!_attached) 
      { 
       Container.AddGestureRecognizer(_longPressRecognizer); 
       _attached = true; 
      } 
     } 

     /// <summary> 
     /// Invoke the command if there is one 
     /// </summary> 
     private void HandleLongClick() 
     { 
      var command = LongPressedEffect.GetCommand(Element); 
      command?.Execute(LongPressedEffect.GetCommandParameter(Element)); 
     } 

     /// <summary> 
     /// Clean the event handler on detach 
     /// </summary> 
     protected override void OnDetached() 
     { 
      if (_attached) 
      { 
       Container.RemoveGestureRecognizer(_longPressRecognizer); 
       _attached = false; 
      } 
     } 

    } 
} 

In XAML

<Label Text="Long Press Me!" effects:LongPressedEffect.Command="{Binding ShowAlertCommand}" effects:LongPressedEffect.CommandParameter="{Binding .}"> 
    <Label.Effects> 
     <effects:LongPressedEffect /> 
    </Label.Effects> 
</Label> 
Verwandte Themen