【问题标题】:Custom control: Button Released event does not fire when swiping away自定义控件:滑开时按钮释放事件不会触发
【发布时间】:2020-03-05 05:24:50
【问题描述】:

我创建了一个自定义控件,该控件使用具有长按操作的按钮。当按钮获得Pressed 时,动作开始。当按钮为Released 时,动作停止。问题是一旦按钮是Pressed,用户可以选择将手指从按钮上滑开。发生这种情况时,Released 事件不会触发,Pressed 事件触发的操作会无限期地运行。

这是我的自定义控件的 XAML 代码:

<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
    x:Class="TestProject.NumericUpDown"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Name="this">

    <ContentView.Content>
        <Button
            x:Name="TestButton"
            Grid.Row="0"
            Grid.Column="0"
            Pressed="TestButton_Pressed"
            Released="TestButton_Released"
            Text="Test" />
    </ContentView.Content>
</ContentView>

在代码隐藏中,我有这些方法来测试事件:

private void TestButton_Pressed(object sender, EventArgs e)
{
    Console.WriteLine("Pressed");
}

private void TestButton_Released(object sender, EventArgs e)
{
    Console.WriteLine("Released");
}

这是我使用用户控件的页面:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="ButtonTest.MainPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:controls="clr-namespace:ButtonTest"
    xmlns:local="clr-namespace:ButtonTest">

    <ScrollView>
        <StackLayout Orientation="Vertical">
            <local:TestControl />
        </StackLayout>
    </ScrollView>

</ContentPage>

我已经读到,按下和释放动作可以中途改变,因为它变成了滑动动作。但是如何检测到这一点,以便取消我由Pressed 事件启动的操作?

更新:这个问题似乎与版本有关。我的项目适用于最新的 Xamarin 版本 4.3。 Visual Studio 2019 默认为 Xamarin 3.4,没有这个问题!如果您想测试此问题,请使用 Xamarin 3.6 或更高版本。

更新 2:我已添加页面 XAML 代码。这包括一个似乎是问题根源的 ScrollView。 StackLayout 没有这个问题。

【问题讨论】:

  • 对不起,我不能完全按照你的话:I have read that a press and release action can change halfway because it becomes a swipe action. But how do I detect this so I can cancel the action I started by the Pressed event?
  • @Jessie 假设我有一个按钮,我会在不释放它的情况下触摸该按钮。如果在那之后我向上移动手指,我开始触摸它,Android 系统开始滚动页面而不是触摸按钮。所以按钮的Pressed 事件被取消或其他东西。这不会触发Released 事件。
  • 对不起,我还是不太关注你。你是怎么开始滚动页面的?这个页面有滚动功能吗?
  • 页面不一定要有滚动功能。在这种情况下,它没有。在我开始触摸按钮后,我只是将手指从按钮上“滑开”。
  • 能否请您添加更多代码,例如您使用它的位置。我试图重现它,并且总是在我身边调用发布事件。

标签: android events button xamarin.forms custom-controls


【解决方案1】:

我遇到了类似的问题。我就是这么来的:

public class CustomButtonRenderer : ButtonRenderer
    {
        public CustomButtonRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);

            if (Control != null && e.NewElement != null)
            {
                Control.Touch += OnTouch;
            }
        }

        private void OnTouch(object sender, TouchEventArgs args)
        {
            var buttonController = (IButtonController)Element;
            if (buttonController == null)
                return;

            var x = (int) args.Event.GetX();
            var y = (int) args.Event.GetY();

            if (!TouchInsideControl(x, y))
            {
                buttonController.SendReleased();
            }
            else if (args.Event.Action  == MotionEventActions.Down)
            {
                buttonController.SendPressed();
            }
            else if (args.Event.Action == MotionEventActions.Up)
            {
                buttonController.SendReleased();
                buttonController.SendClicked();    
            }
        }

        private bool TouchInsideControl(int x, int y)
        {
            return x <= Control.Right && x >= Control.Left && y <= Control.Bottom && y >= Control.Top;
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-02
    • 2018-01-12
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    相关资源
    最近更新 更多