Xamarin.Forms 监听Button的按下、释放事件
工作中遇到这样的一个需求,模仿微信发生语音功能,需要实现按钮按下开始录音,按钮释放录音结束,
Xamarin.Forms中Button没有这样的事件,那么我们如何实现对Button按下,释放两个事件的监听呢?
当然这里我们再次用到了CustomRenderer,一旦遇到Xamrin.Forms无法实现的某些功能,我们就可以
通过CustomRenderer来处理。
首先:我们自定义一个VoiceRecordButton继承于Button
1 using System; 2 using System.Collections.Generic; 3 using System.Diagnostics; 4 using System.Text; 5 using System.Windows.Input; 6 using Xamarin.Forms; 7 8 namespace XFPractice.CustomView 9 { 10 public class VoiceRecordButton: Button 11 { 12 13 public ICommand StartCommand { get; set; } 14 public ICommand EndCommand { get; set; } 15 16 public VoiceRecordButton() 17 { 18 StartCommand = new Command(()=> { 19 Debug.WriteLine(" StartCommand =========== "); 20 }); 21 22 EndCommand = new Command(() => { 23 Debug.WriteLine(" EndCommand =========== "); 24 }); 25 } 26 27 } 28 }
然后分别编写各个平台自己的VoiceRecordButtonRenderer:
通过IOnTouchListener来监听用户对Button的操作。
1 using Android.Views; 2 using XFPractice.CustomView; 3 using XFPractice.Droid.Renderers; 4 using Xamarin.Forms; 5 using Xamarin.Forms.Platform.Android; 6 using static Android.Views.View; 7 8 [assembly: ExportRenderer(typeof(VoiceRecordButton), typeof(VoiceRecordButtonRenderer))] 9 namespace XFPractice.Droid.Renderers 10 { 11 public class VoiceRecordButtonRenderer:ButtonRenderer,IOnTouchListener 12 { 13 VoiceRecordButton view; 14 15 public bool OnTouch(Android.Views.View v, MotionEvent e) 16 { 17 switch(e.Action) 18 { 19 case MotionEventActions.Down: 20 view?.StartCommand?.Execute(""); 21 break; 22 case MotionEventActions.Up: 23 view?.EndCommand?.Execute(""); 24 break; 25 } 26 return true; 27 } 28 29 protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e) 30 { 31 base.OnElementChanged(e); 32 33 Control.SetOnTouchListener(this); 34 35 if (e.NewElement != null) 36 view = e.NewElement as VoiceRecordButton; 37 } 38 39 } 40 }
ios:
通过对TouchDown、TouchUpInside、TouchUpOutside三个事件的处理。
1 using System; 2 using System.Collections.Generic; 3 using System.Diagnostics; 4 using System.Linq; 5 using System.Text; 6 7 using Foundation; 8 using XFPractice.CustomView; 9 using XFPractice.iOS.Renderers; 10 using UIKit; 11 using Xamarin.Forms; 12 using Xamarin.Forms.Platform.iOS; 13 14 [assembly: ExportRenderer(typeof(VoiceRecordButton), typeof(VoiceRecordButtonRenderer))] 15 namespace XFPractice.iOS.Renderers 16 { 17 public class VoiceRecordButtonRenderer : ButtonRenderer 18 { 19 VoiceRecordButton view; 20 21 public VoiceRecordButtonRenderer() 22 { 23 24 } 25 26 27 protected override void OnElementChanged(ElementChangedEventArgs<Button> e) 28 { 29 base.OnElementChanged(e); 30 31 if (e.NewElement != null) 32 view = e.NewElement as VoiceRecordButton; 33 Control.TouchDown += Control_TouchDown; 34 Control.TouchUpInside += Control_TouchUpInside; 35 Control.TouchUpOutside += Control_TouchUpOutside; 36 } 37 38 private void Control_TouchUpOutside(object sender, EventArgs e) 39 { 40 view?.EndCommand?.Execute(""); 41 } 42 43 private void Control_TouchUpInside(object sender, EventArgs e) 44 { 45 view?.EndCommand?.Execute(""); 46 } 47 48 private void Control_TouchDown(object sender, EventArgs e) 49 { 50 view?.StartCommand?.Execute(""); 51 } 52 } 53 }
UWP:
UWP有一个Holding事件,但是对鼠标无效,只对触摸有效,这里我们采用了PointerEventHandler来处理。
1 using XFPractice.CustomView; 2 using XFPractice.UWP.Renderers; 3 using System; 4 using System.Collections.Generic; 5 using System.Diagnostics; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using Windows.UI.Input; 10 using Windows.UI.Xaml.Input; 11 using Xamarin.Forms.Platform.UWP; 12 13 [assembly: ExportRenderer(typeof(VoiceRecordButton), typeof(VoiceRecordButtonRenderer))] 14 namespace XFPractice.UWP.Renderers 15 { 16 public class VoiceRecordButtonRenderer:ButtonRenderer 17 { 18 VoiceRecordButton view; 19 20 21 public VoiceRecordButtonRenderer() 22 { 23 } 24 25 26 27 protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e) 28 { 29 base.OnElementChanged(e); 30 31 32 if (e.NewElement != null) 33 { 34 view = e.NewElement as VoiceRecordButton; 35 } 36 Control.AddHandler(PointerReleasedEvent, new PointerEventHandler(Control_PointerReleased), true); 37 Control.AddHandler(PointerPressedEvent, new PointerEventHandler(Control_PointerPressed), true); 38 } 39 40 private void Control_PointerPressed(object sender, PointerRoutedEventArgs e) 41 { 42 view?.StartCommand?.Execute(""); 43 } 44 45 private void Control_PointerReleased(object sender, PointerRoutedEventArgs e) 46 { 47 view?.EndCommand?.Execute(""); 48 } 49 50 51 } 52 }
这样我们就能监听Button的按下、和释放操作。