maui icon indicating copy to clipboard operation
maui copied to clipboard

Scrolling of Map placed in ScollView does not work.

Open cat0363 opened this issue 1 year ago • 6 comments

The comment of the person who replied to Discussions has been deleted, but it seems to be related to Issue #9827. If this issue is related to #9827, is there a specific solution? This Issue also occurred in Xamarin.Forms, but continues to occur in .NET MAUI.

Discussed in https://github.com/dotnet/maui/discussions/13613

Originally posted by cat0363 March 1, 2023 To reproduce, layout as follows.

<ScrollView Orientation="Vertical">
    <Grid RowDefinitions="100,100,100,100,*,100">
        <Grid Grid.Row="0" BackgroundColor="Red" />
        <Grid Grid.Row="1" BackgroundColor="Yellow" />
        <Grid Grid.Row="2" BackgroundColor="Green" />
        <Grid Grid.Row="3" BackgroundColor="Blue" />
        <Map Grid.Row="4" x:Name="map" HeightRequest="250" WidthRequest="250" VerticalOptions="Start" HorizontalOptions="Start" />
        <Grid Grid.Row="5" BackgroundColor="Purple" />
    </Grid>
</ScrollView>

Code: https://github.com/cat0363/Maui-Issue13628

After scrolling to the Map, when I try to scroll on the map, horizontal scrolling works, but vertical scrolling does not. It seems that the tap event is being handled by the Map's parent control, ScrollView. I want to scroll the map when scrolling on the map placed in the ScrollView.

Since the build environment has not been prepared, it cannot be confirmed for iOS, but at least it is as described for Android.

https://user-images.githubusercontent.com/125236133/222052238-ebfa8077-e7fb-47bd-bc0f-95008c7d8904.mp4

The only solution I found is below.

public override bool DispatchTouchEvent(MotionEvent e) 
{
    if (e.Action == MotionEventActions.Down ||
        e.Action == MotionEventActions.Move ||
        e.Action == MotionEventActions.Up) 
    {
        // Search MapView Control
        var maps = (Window.DecorView as ViewGroup).GetChildrenOfType<MapView>();

        foreach (var map in maps) 
        {
            // Initialize MapView screen position 
            int[] pos = new int[2];
            // Set MapView screen position 
            map.GetLocationOnScreen(pos);
            // Create hit test rectangle 
            Rect hitRect = new Rect(pos[0], pos[1], map.Width, map.Height);
            // Judge hit test
            bool isHitTest = hitRect.Contains(e.GetX(), e.GetY());
            // Hit test result is OK
            if (isHitTest) 
            {
                // Touch event intercept
                map.Parent.RequestDisallowInterceptTouchEvent(true);
            }
        }
    }

    return base.DispatchTouchEvent(e);
}

In the MainActivity.cs file, re-implement DispatchTouchEvent, get the MapView that exists in the page, execute the hit test, and if it is a MapView, intercept the touch event.

https://user-images.githubusercontent.com/125236133/222053763-555131bf-e39b-4adb-bfd6-baf4c9969204.mp4

This works as expected, any other good ideas? I have not confirmed how it works on iOS, so I would like to know if there is no problem with iOS. Thank you.

cat0363 avatar Mar 02 '23 00:03 cat0363

Hi @cat0363. We have added the "s/needs-repro" label to this issue, which indicates that we require steps and sample code to reproduce the issue before we can take further action. Please try to create a minimal sample project/solution or code samples which reproduce the issue, ideally as a GitHub repo that we can clone. See more details about creating repros here: https://github.com/dotnet/maui/blob/main/.github/repro.md

This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

ghost avatar Mar 02 '23 19:03 ghost

I have uploaded the code for this issue to github. https://github.com/cat0363/Maui-Issue13628

Annotation: Please change "YOUR API KEY" in AndroidManifest.xml to the API KEY you are using before executing.

<meta-data android:name="com.google.android.geo.API_KEY" android:value="YOUR API KEY" />

cat0363 avatar Mar 03 '23 01:03 cat0363

We've added this issue to our backlog, and we will work to address it as time and resources allow. If you have any additional information or questions about this issue, please leave a comment. For additional info about issue management, please read our Triage Process.

ghost avatar Mar 07 '23 21:03 ghost

Additional Information: This issue does not occur on iOS. Occurs only on Android.

cat0363 avatar Jul 28 '23 05:07 cat0363

Any updates ?

alzubitariq avatar Mar 22 '24 23:03 alzubitariq

Having the same issue, but with CarouselView with Map

awasilik avatar Apr 11 '24 18:04 awasilik

Your Android solution works perfect, thanks for that! Just a little thing: you have a bug in your code - you don't init the Rect correctly, your code is: Rect hitRect = new Rect(pos[0], pos[1], map.Width, map.Height); while it actually should be: Rect hitRect = new Rect(pos[0], pos[1], pos[0] + map.Width, pos[1] + map.Height);

Also, you forgot to cast float to int when checking intersection: bool isHitTest = hitRect.Contains(e.GetX(), e.GetY()); should be: bool isHitTest = hitRect.Contains((int)e.GetX(), (int)e.GetY());

EitanRa avatar Jul 21 '24 15:07 EitanRa