maui
maui copied to clipboard
Scrolling of Map placed in ScollView does not work.
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.
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.
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" />
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.
Additional Information: This issue does not occur on iOS. Occurs only on Android.
Any updates ?
Having the same issue, but with CarouselView with Map
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());