半路独行

菜鸟的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

 

 

  

 

posted @ 2017-08-25 19:51  半路独行  阅读(1463)  评论(0编辑  收藏  举报