syncfusion / maui-demos

This repository contains the Syncfusion .NET MAUI control’s samples and the guide to use them
200 stars 52 forks source link

SFListView Swiping is not working in Android #46

Open Divyesh-Bhatt opened 7 months ago

Divyesh-Bhatt commented 7 months ago

I've used SFListView control for showing vertical list of data. In that I have to provide Delete feature on Swipe. So I have implemented EndSwipeTemplate.

iOS It is working fine.

Android Not working at all.

Sample Code

<syncfusion:SfListView
    x:Name="listView"
    AllowSwiping="True"
    ItemsSource="{Binding Contacts}"
    SwipeThreshold="100"
    SwipeOffset="150"
    SelectionMode="Multiple"
    SelectionGesture="LongPress"
    ScrollBarVisibility="Always"
    AutoFitMode="Height">
    <syncfusion:SfListView.ItemTemplate x:DataType="model:Contact">
        <DataTemplate x:Name="EndSwipeTemplate" >
            <VerticalStackLayout >
                <local:ContactCard BindingContext="{Binding Path=.}">
                    <local:ContactCard.GestureRecognizers>
                        <TapGestureRecognizer
                                Command="{Binding Path=BindingContext.CardSelectedCommand,
                                                  Source={Reference Name=_contactCardListPage}}" />
                    </local:ContactCard.GestureRecognizers>
                </local:ContactCard>
            </VerticalStackLayout>
        </DataTemplate>
    </syncfusion:SfListView.ItemTemplate>
    <syncfusion:SfListView.EndSwipeTemplate>
        <DataTemplate>
            <Grid BackgroundColor="#DD0000"
                    x:Name="listViewGrid">
                <Grid.GestureRecognizers>
                    <TapGestureRecognizer
                        Command="{Binding Path=BindingContext.DeleteCommand,
                                            Source={x:Reference listView}}"
                        CommandParameter="{Binding .}" />
                </Grid.GestureRecognizers>
                <Label Text="Delete"
                        TextColor="#FFFFFF"
                        HorizontalOptions="Center"
                        FontSize="Small"
                        VerticalOptions="Center">
                </Label>
            </Grid>
        </DataTemplate>
    </syncfusion:SfListView.EndSwipeTemplate>

</syncfusion:SfListView>
SuthiYuvaraj commented 6 months ago

We have checked your requirement , we would like to let you know , we would like to inform you that within the Android platform, touch events are not relayed to the parent view when a child view contains gesture recognizers, as this is standard behavior within the framework. Hence we modified sample with customview, which have gesture and passes the touch to the parent item , Please have look at the sample , Added the customview inside the ItemTemplate , here you can use the GestureRegonizer instead of command in local:ContactCard , Please have a look at the sample and let us know if you have any concerns.

CustomClass.cs

#if ANDROID
    public class CustomContentView : ContentView, ITapGestureListener,IDoubleTapGestureListener,ILongPressGestureListener,ITouchListener
#else
    public class CustomContentView : ContentView
#endif
    {
        public CustomContentView()
        {
#if ANDROID
            this.AddGestureListener(this);
            this.AddTouchListener(this);
#endif
        }

        // Invoke SfListView's ItemTapped , ItemDoubleTapped and ItemLongPress events through ContentView gestures since,
        // touch won't passes to parent view in Android platform when child view has gesture recognizers.
        void ITapGestureListener.OnTap(TapEventArgs e)
        {
            var parent = this.GetParent(this);
            if (parent is ListViewItem)
            {
                (parent as ListViewItem).OnTap(e);
            }
        }

        void ITouchListener.OnTouch(Syncfusion.Maui.Core.Internals.PointerEventArgs e)
        {

            var parent = this.GetParent(this);
            if (parent is ListViewItem)
            {
                (parent as ListViewItem).OnTouch(e);
            }
        }

        void IDoubleTapGestureListener.OnDoubleTap(TapEventArgs e)
        {
            var parent = this.GetParent(this);
            if (parent is ListViewItem)
            {
                (parent as ListViewItem).OnDoubleTap(e);
            }
        }

        void ILongPressGestureListener.OnLongPress(LongPressEventArgs e)
        {
            var parent = this.GetParent(this);
            if (parent is ListViewItem)
            {
                (parent as ListViewItem).OnLongPress(e);
            }
       }

        internal object GetParent(object currentView)
        {
            while (currentView != null && currentView.GetType() != typeof(ListViewItem))
            {
                return this.GetParent((currentView as Element).Parent);
            }

            return currentView;
        }
    }

In XAML

<syncfusion:SfListView x:Name="listView" Grid.Row="1" ScrollBarVisibility="Never" 
ItemSize="60"
AllowSwiping="True"
BackgroundColor="#FFE8E8EC"
ItemsSource="{Binding ToDoList}"
DragStartMode="OnDragIndicator,OnHold"
ItemTapped="listView_ItemTapped"
SelectionMode="None">

<syncfusion:SfListView.ItemTemplate>
<DataTemplate>
<local:CustomContentView>
<local:CustomContentView.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</local:CustomContentView.GestureRecognizers>
<Grid x:Name="rootGrid" Padding="10" BackgroundColor="Beige">
<Label  Text="{Binding Name}"/>
</Grid>
</local:CustomContentView>
</DataTemplate>
</syncfusion:SfListView.ItemTemplate>

SfListViewGesture.zip