* Fixed issue 8198 - ScrollView at CollectionView at RefreshView always leads to Pull-To-Refresh
* Added instructions to the Issue8198
* Added support for WebView on Android to align functionality with iOS
* Added more RefreshView Core Gallery samples
* Updated new samples
* Updated instructions text
--- /dev/null
+using System;
+using System.Threading.Tasks;
+using Xamarin.Forms.CustomAttributes;
+using Xamarin.Forms.Internals;
+
+#if UITEST
+using Xamarin.Forms.Core.UITests;
+using Xamarin.UITest;
+using NUnit.Framework;
+#endif
+
+namespace Xamarin.Forms.Controls.Issues
+{
+#if UITEST
+ [Category(UITestCategories.RefreshView)]
+#endif
+ [Preserve(AllMembers = true)]
+ [Issue(IssueTracker.Github, 8198, "ScrollView at CollectionView at RefreshView always leads to Pull-To-Refresh", PlatformAffected.Android)]
+ public class Issue8198 : TestContentPage
+ {
+ RefreshView _refreshView;
+ Command _refreshCommand;
+
+ protected override void Init()
+ {
+ Title = "Issue 8198";
+
+ var layout = new StackLayout();
+
+ var instructions = new Label
+ {
+ BackgroundColor = Color.Black,
+ TextColor = Color.White,
+ Text = "Scroll the CollectionView to end, lift finger off screen, and then try to scroll up again. If the Refresh Indicator does not appear until it reaches the top, the test has passed."
+ };
+
+ _refreshCommand = new Command(async (parameter) =>
+ {
+ if (!_refreshView.IsRefreshing)
+ {
+ throw new Exception("IsRefreshing should be true when command executes");
+ }
+
+ if (parameter != null && !(bool)parameter)
+ {
+ throw new Exception("Refresh command incorrectly firing with disabled parameter");
+ }
+
+ await Task.Delay(2000);
+ _refreshView.IsRefreshing = false;
+ });
+
+ _refreshView = new RefreshView
+ {
+ Command = _refreshCommand
+ };
+
+ var collectionView = new CollectionView
+ {
+ ItemTemplate = GetDataTemplate(),
+ ItemsSource = new string[]
+ {
+ "Item 1",
+ "Item 2",
+ "Item 3",
+ "Item 4",
+ "Item 5",
+ "item 6",
+ "Item 7",
+ "Item 8",
+ "Item 9",
+ "Item 10",
+ "Item 11",
+ "item 12",
+ "Item 13",
+ "Item 14",
+ "Item 15",
+ "Item 16",
+ "Item 17",
+ "Item 18",
+ "Item 19",
+ "Item 20"
+ }
+ };
+
+ _refreshView.Content = collectionView;
+
+ layout.Children.Add(instructions);
+ layout.Children.Add(_refreshView);
+
+ Content = layout;
+ }
+
+ DataTemplate GetDataTemplate()
+ {
+ var template = new DataTemplate(() =>
+ {
+ var scroll = new ScrollView();
+ var grid = new Grid();
+ grid.RowDefinitions.Add(new RowDefinition() { Height = 40 });
+
+ var cell = new Label();
+ cell.SetBinding(Label.TextProperty, ".");
+ cell.FontSize = 20;
+ cell.BackgroundColor = Color.LightBlue;
+ grid.Children.Add(cell, 0, 0);
+
+ scroll.Content = grid;
+ return scroll;
+ });
+ return template;
+ }
+ }
+}
\ No newline at end of file
<DependentUpon>Issue7886.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Issue7898.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Issue8198.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla22229.xaml">
--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:d="http://xamarin.com/schemas/2014/forms/design"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ mc:Ignorable="d"
+ x:Class="Xamarin.Forms.Controls.GalleryPages.RefreshViewGalleries.RefreshCarouselViewGallery"
+ Title="CarouselView (Pull To Refresh)">
+ <ContentPage.Content>
+ <RefreshView
+ IsRefreshing="{Binding IsRefreshing}"
+ RefreshColor="Pink"
+ Command="{Binding RefreshCommand}"
+ HorizontalOptions="FillAndExpand"
+ VerticalOptions="FillAndExpand">
+ <CarouselView
+ ItemsSource="{Binding Items}">
+ <CarouselView.ItemsLayout>
+ <LinearItemsLayout
+ Orientation="Horizontal"
+ SnapPointsAlignment="Center"
+ SnapPointsType="MandatorySingle"/>
+ </CarouselView.ItemsLayout>
+ <CarouselView.ItemTemplate>
+ <DataTemplate>
+ <ScrollView>
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="*" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <BoxView
+ Grid.Row="0"
+ Color="{Binding Color}"/>
+ <Label
+ Grid.Row="1"
+ Text="{Binding Name}"
+ VerticalOptions="Center"
+ HeightRequest="48"/>
+ </Grid>
+ </ScrollView>
+ </DataTemplate>
+ </CarouselView.ItemTemplate>
+ </CarouselView>
+ </RefreshView>
+ </ContentPage.Content>
+</ContentPage>
\ No newline at end of file
--- /dev/null
+using Xamarin.Forms.Internals;
+
+namespace Xamarin.Forms.Controls.GalleryPages.RefreshViewGalleries
+{
+ [Preserve(AllMembers = true)]
+ public partial class RefreshCarouselViewGallery : ContentPage
+ {
+ public RefreshCarouselViewGallery()
+ {
+ InitializeComponent();
+ BindingContext = new RefreshViewModel();
+ }
+ }
+}
\ No newline at end of file
ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate>
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="48" />
- <ColumnDefinition Width="*" />
- </Grid.ColumnDefinitions>
- <BoxView
- Grid.Column="0"
- Color="{Binding Color}"
- HeightRequest="48"/>
- <Label
- Grid.Column="1"
- Text="{Binding Name}"/>
- </Grid>
+ <ScrollView>
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="48" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <BoxView
+ Grid.Column="0"
+ Color="{Binding Color}"
+ HeightRequest="48"/>
+ <Label
+ Grid.Column="1"
+ Text="{Binding Name}"/>
+ </Grid>
+ </ScrollView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="48" />
- <ColumnDefinition Width="*" />
- </Grid.ColumnDefinitions>
- <BoxView
- Grid.Column="0"
- Color="{Binding Color}"
- HeightRequest="48"/>
- <Label
- Grid.Column="1"
- Text="{Binding Name}"/>
- </Grid>
+ <ScrollView>
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="48" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <BoxView
+ Grid.Column="0"
+ Color="{Binding Color}"
+ HeightRequest="48"/>
+ <Label
+ Grid.Column="1"
+ Text="{Binding Name}"/>
+ </Grid>
+ </ScrollView>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
public RefreshViewGallery()
{
Title = "RefreshView Gallery";
+
+ var button = new Button
+ {
+ Text = "Enable CarouselView",
+ AutomationId = "EnableCarouselView"
+ };
+ button.Clicked += ButtonClicked;
+
Content = new StackLayout
{
Children =
{
+ button,
GalleryBuilder.NavButton("Refresh Layout Gallery", () => new RefreshLayoutGallery(), Navigation),
GalleryBuilder.NavButton("Refresh ScrollView Gallery", () => new RefreshScrollViewGallery(), Navigation),
GalleryBuilder.NavButton("Refresh ListView Gallery", () => new RefreshListViewGallery(), Navigation),
- GalleryBuilder.NavButton("Refresh CollectionView Gallery", () => new RefreshCollectionViewGallery(), Navigation)
+ GalleryBuilder.NavButton("Refresh CollectionView Gallery", () => new RefreshCollectionViewGallery(), Navigation),
+ GalleryBuilder.NavButton("Refresh CarouselView Gallery", () => new RefreshCarouselViewGallery(), Navigation),
+ GalleryBuilder.NavButton("Refresh WebView Gallery", () => new RefreshWebViewGallery(), Navigation)
}
};
}
+
+ void ButtonClicked(object sender, System.EventArgs e)
+ {
+ var button = sender as Button;
+
+ button.Text = "CarouselView Enabled!";
+ button.TextColor = Color.Black;
+ button.IsEnabled = false;
+
+ Device.SetFlags(new[] { ExperimentalFlags.CarouselViewExperimental });
+ }
}
[Preserve(AllMembers = true)]
--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:d="http://xamarin.com/schemas/2014/forms/design"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ mc:Ignorable="d"
+ x:Class="Xamarin.Forms.Controls.GalleryPages.RefreshViewGalleries.RefreshWebViewGallery"
+ Title="WebView (Pull To Refresh)">
+ <ContentPage.Content>
+ <RefreshView
+ IsRefreshing="{Binding IsRefreshing}"
+ Command="{Binding RefreshCommand}"
+ HorizontalOptions="FillAndExpand"
+ VerticalOptions="FillAndExpand">
+ <WebView
+ Source="{Binding Url}"/>
+ </RefreshView>
+ </ContentPage.Content>
+</ContentPage>
\ No newline at end of file
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Windows.Input;
+using Xamarin.Forms.Internals;
+
+namespace Xamarin.Forms.Controls.GalleryPages.RefreshViewGalleries
+{
+ [Preserve(AllMembers = true)]
+ public partial class RefreshWebViewGallery : ContentPage
+ {
+ public RefreshWebViewGallery()
+ {
+ InitializeComponent();
+ BindingContext = new RefreshWebViewGalleryViewModel();
+ }
+ }
+
+ [Preserve(AllMembers = true)]
+ public class RefreshWebViewGalleryViewModel : BindableObject
+ {
+ const int RefreshDuration = 2;
+
+ readonly Random _random;
+ bool _isRefresing;
+ string _url;
+
+ public RefreshWebViewGalleryViewModel()
+ {
+ _random = new Random();
+ LoadUrl();
+ }
+
+ public bool IsRefreshing
+ {
+ get { return _isRefresing; }
+ set
+ {
+ _isRefresing = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public string Url
+ {
+ get { return _url; }
+ set
+ {
+ _url = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public ICommand RefreshCommand => new Command(ExecuteRefresh);
+
+ void LoadUrl()
+ {
+ var urls = new List<string> { "https://dotnet.microsoft.com/apps/xamarin", "https://devblogs.microsoft.com/xamarin/" };
+ int index = _random.Next(urls.Count);
+ Url = urls[index];
+ }
+
+ void ExecuteRefresh()
+ {
+ IsRefreshing = true;
+
+ Device.StartTimer(TimeSpan.FromSeconds(RefreshDuration), () =>
+ {
+ LoadUrl();
+
+ IsRefreshing = false;
+
+ return false;
+ });
+ }
+ }
+}
\ No newline at end of file
<EmbeddedResource Update="GalleryPages\MapWithItemsSourceGallery.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
+ <EmbeddedResource Update="GalleryPages\RefreshViewGalleries\RefreshCarouselViewGallery.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ </EmbeddedResource>
+ <EmbeddedResource Update="GalleryPages\RefreshViewGalleries\RefreshWebViewGallery.xaml">
+ <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+ </EmbeddedResource>
<EmbeddedResource Update="GalleryPages\TitleView.xaml">
<Generator>MSBuild:UpdateDesignTimeXaml</Generator>
</EmbeddedResource>
using Android.Widget;
using Xamarin.Forms.Internals;
using AView = Android.Views.View;
+using AWebView = Android.Webkit.WebView;
namespace Xamarin.Forms.Platform.Android
{
}
if(view is RecyclerView recyclerView)
- return recyclerView.ScrollY < 0;
-
- if (view is global::Android.Widget.ScrollView scrollview)
- return scrollview.ScrollY < 0;
+ return recyclerView.ComputeVerticalScrollOffset() > 0;
if (view is NestedScrollView nestedScrollView)
- return nestedScrollView.ScrollY < 0;
+ return nestedScrollView.ComputeVerticalScrollOffset() > 0;
+
+ if (view is AWebView webView)
+ return webView.ScrollY > 0;
return true;
}