xamarin - 使用 xamarin 表单在 ListView 上添加左右完全滑动手势

标签 xamarin xamarin.forms

enter image description here目前我有一个存储用户药物的 ListView ,我想实现一个滑动手势,以便用户可以简单地向左或向右滑动以判断药物是否已服用。

有没有办法在 ListView 中添加左右完全滑动手势,就像苹果在他们的邮件中实现的方式一样。

最佳答案

注:无法实现指尖跟随移动项,但可以实现左右手势
首先,您应该使用手势构建滑动组件

SwipeGestureGrid.cs

public class SwipeGestureGrid : Grid
{
    #region Private Member
    private double _gestureX { get; set; }
    private double _gestureY { get; set; }
    private bool IsSwipe { get; set; }
    #endregion
    #region Public Member
    #region Events
    #region Tapped
    public event EventHandler Tapped;
    protected void OnTapped(EventArgs e)
    {
        if (Tapped != null)
            Tapped(this, e);
    }
    #endregion
    #region SwipeUP
    public event EventHandler SwipeUP;
    protected void OnSwipeUP(EventArgs e)
    {
        if (SwipeUP != null)
            SwipeUP(this, e);
    }
    #endregion
    #region SwipeDown
    public event EventHandler SwipeDown;
    protected void OnSwipeDown(EventArgs e)
    {
        if (SwipeDown != null)
            SwipeDown(this, e);
    }
    #endregion
    #region SwipeRight
    public event EventHandler SwipeRight;
    protected void OnSwipeRight(EventArgs e)
    {
        if (SwipeRight != null)
            SwipeRight(this, e);
    }
    #endregion
    #region SwipeLeft
    public event EventHandler SwipeLeft;
    protected void OnSwipeLeft(EventArgs e)
    {
        if (SwipeLeft != null)
            SwipeLeft(this, e);
    }
    #endregion
    #endregion
    public double Height
    {
        get
        {
            return HeightRequest;
        }
        set
        {
            HeightRequest = value;
        }
    }
    public double Width
    {
        get
        {
            return WidthRequest;
        }
        set
        {
            WidthRequest = value;
        }
    }
    #endregion
    public SwipeGestureGrid()
    {
        PanGestureRecognizer panGesture = new PanGestureRecognizer();
        panGesture.PanUpdated += PanGesture_PanUpdated;

        TapGestureRecognizer tapGesture = new TapGestureRecognizer();
        tapGesture.Tapped += TapGesture_Tapped;

        GestureRecognizers.Add(panGesture);
        GestureRecognizers.Add(tapGesture);
    }

    private void TapGesture_Tapped(object sender, EventArgs e)
    {
        try
        {
            if (!IsSwipe)
                OnTapped(null);

            IsSwipe = false;
        }
        catch (Exception ex)
        {

        }
    }

    private void PanGesture_PanUpdated(object sender, PanUpdatedEventArgs e)
    {
        try
        {
            switch (e.StatusType)
            {
                case GestureStatus.Running:
                    {
                        _gestureX = e.TotalX;
                        _gestureY = e.TotalY;
                    }
                    break;
                case GestureStatus.Completed:
                    {
                        IsSwipe = true;
                        //Debug.WriteLine("{0}  {1}", _gestureX, _gestureY);
                        if (Math.Abs(_gestureX) > Math.Abs(_gestureY))
                        {
                            if (_gestureX > 0)
                            {
                                OnSwipeRight(null);
                            }
                            else
                            {
                                OnSwipeLeft(null);
                            }
                        }
                        else
                        {
                            if (_gestureY > 0)
                            {
                                OnSwipeDown(null);
                            }
                            else
                            {
                                OnSwipeUP(null);
                            }
                        }
                    }
                    break;
            }
        }
        catch (Exception ex)
        {
        }
    }
}

接下来在 ListView 中使用数据模板并为 GesturecompomentPage.cs 附加事件
   ListView lsvData = new ListView()
    {
        VerticalOptions = LayoutOptions.Fill,
        HorizontalOptions = LayoutOptions.Fill,
        BackgroundColor = Color.White,
        HasUnevenRows = true,
    };
    List<string> lstData = new List<string>();
    public Pages()
    {
        #region DataTemplate
        DataTemplate ListDataTemplate = new DataTemplate(() =>
        {
            #region DataArea of Template
            SwipeGestureGrid gridData = new SwipeGestureGrid()
            {
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand,
                HeightRequest = 60,
                RowDefinitions =
                    {
                        new RowDefinition { },
                    },
                ColumnDefinitions =
                    {
                        new ColumnDefinition { },
                    }
            };
            #endregion
            #region Base of Template
            Grid gridBase = new Grid()
            {
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand,
                HeightRequest = 60,
                RowDefinitions =
                {
                    new RowDefinition { },
                },
                ColumnDefinitions =
                {
                    new ColumnDefinition { },                                                   
                //Put Cells Data here
                    new ColumnDefinition { Width = new GridLength(0, 
                GridUnitType.Absolute)},   //Button for Cells here
                },
            };
            #endregion
            Label lblText = new Label
            {
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand,
                FontAttributes = FontAttributes.Bold,
                VerticalTextAlignment = TextAlignment.End,
                TextColor = Color.Black,
                BackgroundColor = Color.Silver,
                LineBreakMode = LineBreakMode.TailTruncation,
                FontSize = 18,
            };
            lblText.SetBinding(Label.TextProperty, ".");

            ImageButton btnCellDelete = new ImageButton() { Source = "Delete" };

            gridData.Children.Add(lblText, 0, 0);

            gridBase.Children.Add(gridData, 0, 0);
            gridBase.Children.Add(btnCellDelete, 1, 0);

            gridData.SwipeLeft += GridTemplate_SwipeLeft;
            gridData.SwipeRight += GridTemplate_SwipeRight; ;
            gridData.Tapped += GridTemplate_Tapped; ;
            btnCellDelete.Clicked += BtnCellDelete_Clicked; ;

            return new ViewCell
            {
                View = gridBase,
                Height = 60,
            };
        });

        #endregion
        for (int i = 1; i <= 100; i++)
        {
            lstData.Add(i.ToString());
        }
        lsvData.ItemTemplate = ListDataTemplate;
        lsvData.ItemsSource = lstData;
        Content = lsvData;
    }

添加 event.SwipeLeft 以显示 DeleteButton
   private void GridTemplate_SwipeLeft(object sender, EventArgs e)
{
    try
    {
        if (sender is SwipeGestureGrid)
        {
            var templateGrid = ((SwipeGestureGrid)sender).Parent;
            if (templateGrid != null && templateGrid is Grid)
            {
                var CellTemplateGrid = (Grid)templateGrid;
                CellTemplateGrid.ColumnDefinitions[1].Width = new GridLength(60, GridUnitType.Absolute);
            }
        }

    }
    catch (Exception ex)
    {

    }
}

向右滑动以隐藏删除按钮
private void GridTemplate_SwipeRight(object sender, EventArgs e)
{
    try
    {
        if (sender is SwipeGestureGrid)
        {
            var templateGrid = ((SwipeGestureGrid)sender).Parent;
            if (templateGrid != null && templateGrid is Grid)
            {
                var CellTemplateGrid = (Grid)templateGrid;
                CellTemplateGrid.ColumnDefinitions[1].Width = new GridLength(0, GridUnitType.Absolute);
            }
        }
    }
    catch (Exception ex)
    {

    }
}

删除按钮点击事件
 private void BtnCellDelete_Clicked(object sender, EventArgs e)
{
    try
    {
        if (sender is ImageButton)
        {
            var templateGrid = ((ImageButton)sender);
            //templateGrid.Parent = gridBase
            //templateGrid.Parent.Parent = cell
            if (templateGrid.Parent != null && templateGrid.Parent.Parent != null && templateGrid.Parent.Parent.BindingContext != null && templateGrid.Parent.Parent.BindingContext is string)
            {
                var deletedate = templateGrid.Parent.Parent.BindingContext as string;
                lstData.RemoveAll(f => f == deletedate);
                lsvData.ItemsSource = null;
                lsvData.ItemsSource = lstData;
            }
        }
    }
    catch (Exception ex)
    {

    }
}

有所有代码。
https://github.com/act70255/ListViewSwipeGesture

关于xamarin - 使用 xamarin 表单在 ListView 上添加左右完全滑动手势,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55649769/

相关文章:

android - 无法从 apk/res-auto 命名空间访问项目资源

xamarin - com.apple.AuthenticationServices.Authorization 错误代码 1000

azure - 如果从另一台计算机构建,UWP 推送通知将停止工作

xaml - 如何在 Xamarin 中重用相同的 View ? XAML

c# - 隐藏在 Xamarin Forms Android 中时如何禁用单击 TabbedPage 菜单项?

ios - xamarin 表单中的钥匙串(keychain)配置

ios - Xamarin iOS - 创建绑定(bind) - 对于经典、统一和形式,我是否需要不同的绑定(bind)?

google-analytics - Xamarin googlePlayServiceComponent Analytics TrackEvent不起作用

c# - 在 Android Xamarin.forms 上的整个应用程序中保持沉浸式模式

xaml - 如何建议从 Xamarin.Forms XAML 中的隐式样式继承?