Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Fix SwipeView not swiping using Label as direct content #14824

Merged
merged 17 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public SwipeViewGallery()
Children =
{
GalleryBuilder.NavButton("Basic SwipeView Gallery", () => new BasicSwipeGallery(), Navigation),
GalleryBuilder.NavButton("SwipeView without Layout Content Gallery", () => new SwipeViewNoLayoutGallery(), Navigation),
GalleryBuilder.NavButton("SwipeView Threshold Gallery", () => new SwipeThresholdGallery(), Navigation),
GalleryBuilder.NavButton("SwipeView Events Gallery", () => new SwipeViewEventsGallery(), Navigation),
GalleryBuilder.NavButton("SwipeItems from Resource Gallery", () => new ResourceSwipeItemsGallery(), Navigation),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?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"
x:Class="Maui.Controls.Sample.Pages.SwipeViewGalleries.SwipeViewNoLayoutGallery"
Title="SwipeView without Content Layout">
<ContentPage.Content>
<StackLayout>
<SwipeView
HorizontalOptions="Center"
VerticalOptions="Center"
Margin="12">
<SwipeView.RightItems>
<SwipeItems
Mode="Execute">
<SwipeItem
Text="Delete"
IconImageSource="coffee.png"
BackgroundColor="Red"
Invoked="OnInvoked"/>
</SwipeItems>
</SwipeView.RightItems>
<SwipeView.Content>
<Label
HeightRequest="60"
WidthRequest="300"
BackgroundColor="LightGray"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
Text="Swipe Left (Execute)"/>
</SwipeView.Content>
</SwipeView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using Microsoft.Maui.Controls.Internals;
using Microsoft.Maui.Controls.Xaml;

namespace Maui.Controls.Sample.Pages.SwipeViewGalleries
{
[Preserve(AllMembers = true)]
[XamlCompilation(XamlCompilationOptions.Skip)]
public partial class SwipeViewNoLayoutGallery
{
public SwipeViewNoLayoutGallery()
{
InitializeComponent();
}

async void OnInvoked(object sender, EventArgs e)
{
await DisplayAlert("SwipeView", "SwipeItem Invoked", "OK");
}
}
}
41 changes: 23 additions & 18 deletions src/Core/src/Platform/Android/MauiSwipeView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,31 +115,36 @@ bool ShouldInterceptTouch(MotionEvent? e)

bool ShouldInterceptScrollChildrenTouch(SwipeDirection swipeDirection)
{
if (!(_contentView is ViewGroup viewGroup) || _initialPoint == null)
if (_contentView is null || _initialPoint is null)
return false;

int x = (int)(_initialPoint.X * _density);
int y = (int)(_initialPoint.Y * _density);
var viewGroup = _contentView as ViewGroup;

bool isHorizontal = swipeDirection == SwipeDirection.Left || swipeDirection == SwipeDirection.Right;

for (int i = 0; i < viewGroup.ChildCount; i++)
if (viewGroup is not null)
{
var child = viewGroup.GetChildAt(i);

if (child != null && IsViewInBounds(child, x, y))
{
if (child is AbsListView absListView)
return ShouldInterceptScrollChildrenTouch(absListView, isHorizontal);
int x = (int)(_initialPoint.X * _density);
int y = (int)(_initialPoint.Y * _density);

if (child is RecyclerView recyclerView)
return ShouldInterceptScrollChildrenTouch(recyclerView, isHorizontal);
bool isHorizontal = swipeDirection == SwipeDirection.Left || swipeDirection == SwipeDirection.Right;

if (child is NestedScrollView scrollView)
return ShouldInterceptScrollChildrenTouch(scrollView, isHorizontal);
for (int i = 0; i < viewGroup.ChildCount; i++)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'i' is just used to access the index, why don't we use a foreach in the collection? If we are worried about the performance of foreach vs for, we have bigger problems.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is mostly used to get the child using the GetChildAt method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mandel-macaque's feedback seems to still be valid here, unless I'm missing something

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can ignore it. Is not a blocker.

{
var child = viewGroup.GetChildAt(i);

if (child is AWebView webView)
return ShouldInterceptScrollChildrenTouch(webView, isHorizontal);
if (child != null && IsViewInBounds(child, x, y))
{
switch (child)
{
case AbsListView absListView:
return ShouldInterceptScrollChildrenTouch(absListView, isHorizontal);
case RecyclerView recyclerView:
return ShouldInterceptScrollChildrenTouch(recyclerView, isHorizontal);
case NestedScrollView scrollView:
return ShouldInterceptScrollChildrenTouch(scrollView, isHorizontal);
case AWebView webView:
return ShouldInterceptScrollChildrenTouch(webView, isHorizontal);
}
}
}
}

Expand Down