菜鸟的Xamarin.Forms前行之路——按钮的按下抬起事件的监控(可扩展至其他事件)
提问:监控按钮的点击事件,可以通过按钮的Click事件,或者Command绑定,那么如何监控按钮的按下与抬起,或者移动,长按,双击等事件?
解决方法:各个平台自定义渲染依赖注入.
共享项目PCL:
1先定义一个继承Button的实体类NewButton.cs
public class NewButton : 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定义一个NewButton的控件TestControl(相当新建一个页面,只不过是个部分页面,继承contentView而不是contentpage )
xaml:
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Sample.TestControl"> <ContentView.Content> <StackLayout x:Name="TheContent"> </StackLayout> </ContentView.Content> </ContentView>
cs:
public partial class TestControl: ContentView { public TestControl() { InitializeComponent(); var myButton = new NewButton { Text = "自定义按钮", HorizontalOptions = LayoutOptions.FillAndExpand }; TheContent.Children.Add(myButton); myButton.Pressed += (sender, args) => { myButton.BackgroundColor = Color.Red; }; myButton.Released += (sender, args) => { myButton.BackgroundColor = Color.Blue; }; } }
Android项目:
添加一个NewButtonRenderer.cs文件自定义渲染并注入:
[assembly: ExportRenderer(typeof(NewButton), typeof(NewButtonRenderer))] namespace Sample.Droid { class NewButtonRenderer: ButtonRenderer { protected override void OnElementChanged(ElementChangedEventArgs<Button> e) { base.OnElementChanged(e); var TestButton = e.NewElement as NewButton; var thisButton = Control as Android.Widget.Button; thisButton.Touch += (object sender, TouchEventArgs args) => { if (args.Event.Action == MotionEventActions.Down) { TestButton.OnPressed(); } else if (args.Event.Action == MotionEventActions.Up) { TestButton.OnReleased(); } }; } } }
Ios项目:
类似安卓项目,也是自定义渲染和注入
[assembly: ExportRenderer(typeof(NewButton), typeof(NewButtonRenderer))] namespace Sample.iOS { public class NewButtonRenderer : ButtonRenderer { protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e) { base.OnElementChanged(e); var TestButton = e.NewElement as NewButton; var thisButton = Control as UIButton; thisButton.TouchDown += delegate { TestButton.OnPressed(); }; thisButton.TouchUpInside += delegate { TestButton.OnReleased(); }; } } }
这样共享项目和2个平台之间的方法就实现了统一,在按下与抬起的时候,都能够监控事件
用法:
在布局页面引入控件(上述TestControl)所在的命名空间,然后引入控件即可,例:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:controls="clr-namespace:Sample" x:Class="Sample.TestPage"> <StackLayout> <controls:TestControl /> </StackLayout> </ContentPage>
扩展:
因为这些方法都是自己在平台自定义渲染的,所以可以很方便的监控原生事件,例如长按,双击等等,只需要基本了解一下安卓和苹果的东西,再结合上述的例子,就很容易扩展了
git项目地址: https://github.com/weiweu/TestProject/tree/dev