如何实现以xamarin形式(如本机功能)删除的滑动?

时间:2019-01-09 06:33:38

标签: c# xamarin.forms

借助这篇帖子Xamarin Forms slide button,我已经实现了滑动删除xamarin形式的功能的功能

但是我还需要其他东西。根据我的要求,幻灯片应该从右到左移动,并且按钮应该出现在滑块后面或红色区域中,当我单击它时,应该触发一个事件。

这是.cs文件

public class SlideToActView : AbsoluteLayout
{
    public static readonly BindableProperty ThumbProperty =
        BindableProperty.Create(
            "Thumb", typeof(View), typeof(SlideToActView),
            defaultValue: default(View));

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

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

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

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

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

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

        _gestureListener = new ContentView { BackgroundColor = Color.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 (Thumb == null || TrackBar == null || FillBar == null)
            return;

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

            case GestureStatus.Running:
                // Translate and ensure we don't pan beyond the wrapped user interface element bounds.
                var x = Math.Max(0, e.TotalX);
                if (x > (Width - Thumb.Width))
                    x = (Width - Thumb.Width);

                //Uncomment this if you want only forward dragging.
                //if (e.TotalX < Thumb.TranslationX)
                //    return;
                Thumb.TranslationX = x;
                SetLayoutBounds(FillBar, new Rectangle(0, 0, x + Thumb.Width / 2, this.Height));
                break;

            case GestureStatus.Completed:
                var posX = Thumb.TranslationX;
                SetLayoutBounds(FillBar, new Rectangle(0, 0, 0, this.Height));

                // Reset translation applied during the pan
                await Task.WhenAll(new Task[]{
                TrackBar.FadeTo(1, _animLength),
                Thumb.TranslateTo(0, 0, _animLength * 2, Easing.CubicIn),
            });

                if (posX >= (Width - Thumb.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 (Thumb == null || TrackBar == null || FillBar == null)
            return;


        Children.Clear();

        SetLayoutFlags(TrackBar, AbsoluteLayoutFlags.SizeProportional);
        SetLayoutBounds(TrackBar, new Rectangle(0, 0, 1, 1));
        Children.Add(TrackBar);

        SetLayoutFlags(FillBar, AbsoluteLayoutFlags.None);
        SetLayoutBounds(FillBar, new Rectangle(0, 0, 0, this.Height));
        Children.Add(FillBar);

        SetLayoutFlags(Thumb, AbsoluteLayoutFlags.None);
        SetLayoutBounds(Thumb, new Rectangle(0, 0, this.Width / 5, this.Height));
        Children.Add(Thumb);

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


    }
}

这是xaml

 <StackLayout Margin="40">

                <slidetoact:SlideToActView HeightRequest="50">
                    <slidetoact:SlideToActView.Thumb>
                        <Frame CornerRadius="10" HasShadow="false" BackgroundColor="Silver" Padding="0">
                            <Image Source="icon.png" HorizontalOptions="Center" VerticalOptions="Center" HeightRequest="40" WidthRequest="40" />
                        </Frame>
                    </slidetoact:SlideToActView.Thumb>

                    <slidetoact:SlideToActView.TrackBar>
                        <Frame CornerRadius="10" HasShadow="false" BackgroundColor="Gray" Padding="0">
                            <Label Text="Slide 'x' to cancel" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" />
                        </Frame>
                    </slidetoact:SlideToActView.TrackBar>

                    <slidetoact:SlideToActView.FillBar>
                        <Frame CornerRadius="10" HasShadow="false" BackgroundColor="Red" Padding="0">
                            <Button Text="Delete" Clicked="Handle_SlideCompleted" BackgroundColor="Red" TextColor="White"></Button>
                        </Frame>
                    </slidetoact:SlideToActView.FillBar>
                </slidetoact:SlideToActView>
                <Label x:Name="MessageLbl" FontAttributes="Bold" TextColor="Red" />
            </StackLayout>

我希望幻灯片应该从右到左移动,并且按钮应该出现在滑块后面或红色区域中,当我单击它时,应该会触发一个事件。

0 个答案:

没有答案