Description
Context
I'm migrating a Xamarin.Forms application to .NET MAUI (.NET 10). The app displays web content inside a WebView wrapped in a RefreshView to allow users to manually refresh the page.
Expected Behavior
When the user scrolls up inside the WebView, the pull-to-refresh gesture should only trigger when the WebView content is already at the top (scroll position = 0). This is the standard behavior users expect, similar to how browsers or native apps handle pull-to-refresh with scrollable content.
Actual Behavior
On Android only, the pull-to-refresh is triggered immediately when the user scrolls up, even if the WebView content is not at the top. This makes it nearly impossible to scroll up through the web content without accidentally triggering a refresh.
iOS works correctly — the pull-to-refresh only activates when the WebView is scrolled to the top.
Steps to Reproduce
- Create a new MAUI application targeting Android and iOS
- Add a RefreshView containing a WebView
- Load a page with scrollable content (e.g., any news website)
- Scroll down in the WebView
- Try to scroll back up
Result on Android:
Pull-to-refresh indicator appears immediately when scrolling up, even when not at the top of the page.
Result on iOS:
Pull-to-refresh only triggers when the content is at the top.
Minimal Reproduction Code
XAML:
<?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="MauiApp.MainPage">
<RefreshView IsRefreshing="{Binding IsRefreshing}"
Command="{Binding RefreshCommand}">
<WebView Source="https://example.com"
HorizontalOptions="Fill"
VerticalOptions="Fill" />
</RefreshView>
</ContentPage>
ViewModel:
public partial class MainViewModel : ObservableObject
{
[ObservableProperty]
private bool isRefreshing;
[RelayCommand]
private async Task Refresh()
{
// Simulate refresh
await Task.Delay(1000);
IsRefreshing = false;
}
}
Root Cause Analysis
After investigation, the issue seems to be related to how Android's SwipeRefreshLayout (which backs RefreshView on Android) determines whether its child content can scroll up.
SwipeRefreshLayout triggers pull-to-refresh when it believes the child "cannot scroll up" (i.e., is at the top). However, WebView is not recognized as a standard scrollable view by SwipeRefreshLayout, so it incorrectly assumes the content is always at the top.
On iOS, WKWebView is backed by UIScrollView, which correctly communicates its scroll state to the parent refresh control.
Environment
.NET Version: 10.0
MAUI Version: (latest as of January 2026)
IDE: Visual Studio 2022 / JetBrains Rider
Target OS: Android 14/15 (API 34/35)
Tested devices: Pixel emulator, Samsung Galaxy physical device
Related Issues
This appears to be a known limitation that was also present in Xamarin.Forms and may be related to:
The documented constraint that RefreshView expects a scrollable child (ScrollView, CollectionView, etc.)
WebView not being listed as a supported scrollable content type for RefreshView
Questions
Is this a known limitation or a bug?
Is there a recommended approach for using RefreshView with WebView on Android?
Are there plans to improve SwipeRefreshLayout integration with WebView in future MAUI releases?
Link to public reproduction project repository
No response
Version with bug
10.0.20
Is this a regression from previous behavior?
Not sure, did not test other versions
Last version that worked well
No response
Affected platforms
Android
Affected platform versions
No response
Did you find any workaround?
No response
Relevant log output
Description
Context
I'm migrating a Xamarin.Forms application to .NET MAUI (.NET 10). The app displays web content inside a
WebViewwrapped in aRefreshViewto allow users to manually refresh the page.Expected Behavior
When the user scrolls up inside the
WebView, the pull-to-refresh gesture should only trigger when theWebViewcontent is already at the top (scroll position = 0). This is the standard behavior users expect, similar to how browsers or native apps handle pull-to-refresh with scrollable content.Actual Behavior
On Android only, the pull-to-refresh is triggered immediately when the user scrolls up, even if the
WebViewcontent is not at the top. This makes it nearly impossible to scroll up through the web content without accidentally triggering a refresh.iOS works correctly — the pull-to-refresh only activates when the
WebViewis scrolled to the top.Steps to Reproduce
Result on Android:
Pull-to-refresh indicator appears immediately when scrolling up, even when not at the top of the page.
Result on iOS:
Pull-to-refresh only triggers when the content is at the top.
Minimal Reproduction Code
XAML:
ViewModel:
Root Cause Analysis
After investigation, the issue seems to be related to how Android's SwipeRefreshLayout (which backs RefreshView on Android) determines whether its child content can scroll up.
SwipeRefreshLayout triggers pull-to-refresh when it believes the child "cannot scroll up" (i.e., is at the top). However, WebView is not recognized as a standard scrollable view by SwipeRefreshLayout, so it incorrectly assumes the content is always at the top.
On iOS, WKWebView is backed by UIScrollView, which correctly communicates its scroll state to the parent refresh control.
Environment
.NET Version: 10.0
MAUI Version: (latest as of January 2026)
IDE: Visual Studio 2022 / JetBrains Rider
Target OS: Android 14/15 (API 34/35)
Tested devices: Pixel emulator, Samsung Galaxy physical device
Related Issues
This appears to be a known limitation that was also present in Xamarin.Forms and may be related to:
The documented constraint that RefreshView expects a scrollable child (ScrollView, CollectionView, etc.)
WebView not being listed as a supported scrollable content type for RefreshView
Questions
Is this a known limitation or a bug?
Is there a recommended approach for using RefreshView with WebView on Android?
Are there plans to improve SwipeRefreshLayout integration with WebView in future MAUI releases?
Link to public reproduction project repository
No response
Version with bug
10.0.20
Is this a regression from previous behavior?
Not sure, did not test other versions
Last version that worked well
No response
Affected platforms
Android
Affected platform versions
No response
Did you find any workaround?
No response
Relevant log output