如何在MAUI App中实现滑动按钮(带事件)?

问题描述 投票:0回答:1

如何在 MAUI 应用程序中使用事件来实现滑动按钮? 寻找一个带有图像或图标的按钮,可以向左或右端滑动。

附示例图片

maui swipe-gesture
1个回答
0
投票

要在 MAUI 中实现带有事件的滑动按钮,您需要编写一个代表拇指和轨迹栏的自定义控件,并且还可以在滑动操作完成时调用

SlideCompleted()
事件。

以下是演示供您参考:

  1. 创建一个自定义控件:MySlideView.cs,实现
    AbsoluteLayout
    :
   public class MySlideView : AbsoluteLayout
    {

        public View MyTrackBar
        {
            get { return (View)GetValue(TrackBarProperty); }
            set { SetValue(TrackBarProperty, value); }
        }

        public static readonly BindableProperty TrackBarProperty =
            BindableProperty.Create(
                "MyTrackBar", typeof(View), typeof(MySlideView),
                defaultValue: default(View));

        public View MyFillBar
        {
            get { return (View)GetValue(FillBarProperty); }
            set { SetValue(FillBarProperty, value); }
        }

        public static readonly BindableProperty FillBarProperty =
            BindableProperty.Create(
                "MyFillBar", typeof(View), typeof(MySlideView),
                defaultValue: default(View));

        public View MyThumb
        {
            get { return (View)GetValue(ThumbProperty); }
            set { SetValue(ThumbProperty, value); }
        }

        public static readonly BindableProperty ThumbProperty =
       BindableProperty.Create(
           "MyThumb", typeof(View), typeof(MySlideView),
           defaultValue: default(View));

   
        private PanGestureRecognizer _panGesture = new PanGestureRecognizer();
        private View _gestureListener;
        public MySlideView()
        {
            _panGesture.PanUpdated += OnPanGestureUpdated;
            SizeChanged += OnSizeChanged;

            _gestureListener = new ContentView { BackgroundColor = Colors.White, Opacity = 0.05 };
            _gestureListener.GestureRecognizers.Add(_panGesture);
        }

        public event EventHandler SlideCompleted;

        private const double _fadeEffect = 0.5;
        private const uint _animLength = 50;
        async void OnPanGestureUpdated(object sender, PanUpdatedEventArgs e)
        {
            if (MyThumb == null || MyTrackBar == null || MyFillBar == null)
                return;

            switch (e.StatusType)
            {
                case GestureStatus.Started:
                    await MyTrackBar.FadeTo(_fadeEffect, _animLength);
                    break;

                case GestureStatus.Running:
                   
                    var x = Math.Max(0, e.TotalX);
                    var y = Math.Max(0, e.TotalY);
                    if (x > (Width - MyThumb.Width))
                        x = (Width - MyThumb.Width);
                    if (y > (Height - MyThumb.Height)) y = (Height - MyThumb.Height);

                    MyThumb.TranslationX = x;
                    SetLayoutBounds((IView)MyFillBar, new Rect(0, 0, x + MyThumb.Width / 2, Height));
                    break;

                case GestureStatus.Completed:
                    var posX = MyThumb.TranslationX;
                    SetLayoutBounds((IView)MyFillBar, new Rect(0, 0, 0, this.Height));

                   
                    await Task.WhenAll(new Task[]{
                    MyTrackBar.FadeTo(1, _animLength),
                    MyThumb.TranslateTo(0, 0, _animLength * 2, Easing.CubicIn),
                });

                    if (posX >= (Width - MyThumb.Width - 10/* keep some margin for error*/))
                        SlideCompleted?.Invoke(this, EventArgs.Empty);
                    break;
            }
        }

        void OnSizeChanged(object sender, EventArgs e)
        {
            if (Width == 0 || Height == 0)
                return;
            if (MyThumb == null || MyTrackBar == null || MyFillBar == null)
                return;


            Children.Clear();

            SetLayoutFlags((IView)MyTrackBar, AbsoluteLayoutFlags.SizeProportional);
            SetLayoutBounds((IView)MyTrackBar, new Rect(0, 0, 1, 1));
            Children.Add(MyTrackBar);

            SetLayoutFlags((IView)MyFillBar, AbsoluteLayoutFlags.None);
            SetLayoutBounds((IView)MyFillBar, new Rect(0, 0, 0, this.Height));
            Children.Add(MyFillBar);

            SetLayoutFlags((IView)MyThumb, AbsoluteLayoutFlags.None);
            SetLayoutBounds((IView)MyThumb, new Rect(0, 0, this.Width / 5, this.Height));
            Children.Add(MyThumb);

            SetLayoutFlags((IView)_gestureListener, AbsoluteLayoutFlags.SizeProportional);
            SetLayoutBounds((IView)_gestureListener, new Rect(0, 0, 1, 1));
            Children.Add(_gestureListener);

        }
    }

XAML:



<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MauiAppSwipe"
             x:Class="MauiAppSwipe.MainPage">

 
   <VerticalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="Center">


        <local:MySlideView HeightRequest="60" SlideCompleted="SlideCompleted">
            <local:MySlideView.MyThumb>
                <Frame  BackgroundColor="AliceBlue" Padding="0" Margin="-20,0,0,0" HeightRequest="60" WidthRequest="60" >
                    <Image Source="dotnet_bot.png" Aspect="AspectFit"  VerticalOptions="Center" HorizontalOptions="Center" HeightRequest="60" WidthRequest="60" />
                </Frame>
            </local:MySlideView.MyThumb>

            <local:MySlideView.MyTrackBar>
                <Frame  BackgroundColor="DarkGray" Padding="0">
                    <Label TextColor="White" Text="SWIPE TO ACTIVATE" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" />
                </Frame>
            </local:MySlideView.MyTrackBar>

            <local:MySlideView.MyFillBar>
                <Frame  BackgroundColor="Transparent" Padding="0" />
            </local:MySlideView.MyFillBar>
        </local:MySlideView>


      </VerticalStackLayout>

</ContentPage>

隐藏代码:


public partial class MainPage : ContentPage
{
  
      public MainPage()
      {
            InitializeComponent();
      }



    private void SlideCompleted(object sender, EventArgs e)
    {
       //Raise SlideCompleted() event when the slide action is completed.
    }
}

输出:

© www.soinside.com 2019 - 2024. All rights reserved.