using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using Xamarin.Forms.CustomAttributes; using Xamarin.Forms.Internals; #if UITEST using NUnit.Framework; using Xamarin.UITest; #endif namespace Xamarin.Forms.Controls.TestCasesPages { [Preserve (AllMembers=true)] [Issue (IssueTracker.Github, 2411, "ListView.ScrollTo not working in TabbedPage", PlatformAffected.Android)] public class Issue2411 : TestTabbedPage { protected override void Init () { Children.Add (new XamarinListViewScrollToBugPage1 ()); Children.Add (new XamarinListViewScrollToBugPage2 ()); Children.Add (new XamarinListViewScrollToBugPage3 ()); } #if UITEST [Test] #if __ANDROID__ [Ignore ("Appearing event is tied to virtualization in TabbedPage for Material")] #endif [Issue (IssueTracker.Github, 2411, "ScrollToPositon.MakeVisible not called every time TabbedPage", PlatformAffected.Android)] public void Issue2411ScrollToPositionMakeVisible () { RunningApp.WaitForElement (q => q.Marked ("99 99 99 99 99 99")); RunningApp.Screenshot ("ScrollTo working correctly"); RunningApp.Tap (q => q.Marked ("Crash in ScrollToPosition.End")); RunningApp.Screenshot ("On Second Tab"); RunningApp.WaitForElement (q => q.Marked ("2 0 0 0 0 0 0")); RunningApp.Tap (q => q.Marked ("Scroll To in OnAppearing")); RunningApp.Screenshot ("On First Tab"); RunningApp.WaitForElement (q => q.Marked ("99 99 99 99 99 99")); var listViewBound = RunningApp.Query (q => q.Marked ("listView"))[0].Rect; Xamarin.Forms.Core.UITests.Gestures.ScrollForElement (RunningApp, "* marked:'0 0 0 0 0 0'", new Xamarin.Forms.Core.UITests.Drag (listViewBound, Xamarin.Forms.Core.UITests.Drag.Direction.TopToBottom, Xamarin.Forms.Core.UITests.Drag.DragLength.Long)); RunningApp.Screenshot ("Scrolled to Top"); RunningApp.Tap (q => q.Marked ("Crash in ScrollToPosition.End")); RunningApp.Screenshot ("On Second Tab"); RunningApp.WaitForElement (q => q.Marked ("2 0 0 0 0 0 0")); RunningApp.Tap (q => q.Marked ("Scroll To in OnAppearing")); RunningApp.Screenshot ("On First Tab"); RunningApp.WaitForElement (q => q.Marked ("99 99 99 99 99 99")); } [Test] [Issue (IssueTracker.Github, 2411, "ScrollToPositon.End crashing in TabbedPage", PlatformAffected.Android)] public void Issue2411ScrollToPositionEndCrash () { RunningApp.Tap (q => q.Marked ("Crash in ScrollToPosition.End")); RunningApp.Screenshot ("On Second Tab"); RunningApp.Tap (q => q.Marked ("Scroll To in OnAppearing")); RunningApp.Screenshot ("On First Tab"); RunningApp.Tap (q => q.Marked ("Crash in ScrollToPosition.End")); RunningApp.Screenshot ("On Second Tab Again"); RunningApp.Tap (q => q.Marked ("ScrollToPosition.End End - Not animated")); RunningApp.WaitForElement (q => q.Marked ("2 99 99 99 99 99 99")); } [Test] [Issue (IssueTracker.Github, 2411, "ScrollToPositon.End crashing in TabbedPage", PlatformAffected.Android)] public void Issue2411ScrollToPositionWrongOnUneven () { RunningApp.Tap (q => q.Marked ("Crash in ScrollToPosition.End")); RunningApp.Tap (q => q.Marked ("Scroll To in OnAppearing Uneven")); RunningApp.Screenshot ("On Third Tab"); RunningApp.WaitForElement (q => q.Marked ("99 99 99 99 99 99")); } #endif } [Preserve (AllMembers = true)] internal class ListObj { public string Name { get; set; } } [Preserve (AllMembers = true)] public class CellTemplateScrollTo : ViewCell { public CellTemplateScrollTo () { Label cellLabel = new Label () { HorizontalOptions = LayoutOptions.FillAndExpand, }; cellLabel.SetBinding (Label.TextProperty, new Binding ("Name", BindingMode.OneWay)); StackLayout root = new StackLayout () { Children = { cellLabel } }; View = root; } } [Preserve (AllMembers = true)] public class CellTemplateScrollToUneven : CellTemplateScrollTo { public CellTemplateScrollToUneven () { Height = 60 + new Random().Next(10, 100); } } [Preserve (AllMembers = true)] public class XamarinListViewScrollToBugPage1 : ContentPage { ListView _listView; ObservableCollection _collection = new ObservableCollection (); public XamarinListViewScrollToBugPage1 () { Title = "Scroll To in OnAppearing"; for (int i = 0; i < 100; i++) { var item = new ListObj { Name = string.Format ("{0} {0} {0} {0} {0} {0}", i) }; _collection.Add (item); } _listView = new ListView { ItemsSource = _collection, ItemTemplate = new DataTemplate (typeof(CellTemplateScrollTo)) }; _listView.AutomationId = "listView"; Content = new StackLayout { Children = { _listView } }; } protected override void OnAppearing () { base.OnAppearing (); _listView.ScrollTo (_collection.Last(), ScrollToPosition.MakeVisible, false); } } [Preserve (AllMembers = true)] public class XamarinListViewScrollToBugPage2 : ContentPage { ListView _listView; ObservableCollection _collection = new ObservableCollection (); public XamarinListViewScrollToBugPage2 () { Title = "Crash in ScrollToPosition.End"; for (int i = 0; i < 100; i++) { var item = new ListObj { Name = string.Format ("2 {0} {0} {0} {0} {0} {0}", i) }; _collection.Add (item); } _listView = new ListView { ItemsSource = _collection, ItemTemplate = new DataTemplate (typeof(CellTemplateScrollTo)) }; var endButton = new Button { Text = "ScrollToPosition.End End - Not animated", Command = new Command (() => { _listView.ScrollTo (_collection.Last(), ScrollToPosition.End, false); }) }; var endButtonAnimated = new Button { Text = "ScrollToPosition.MakeVisible End - Animated", Command = new Command (() => { _listView.ScrollTo (_collection.Last(), ScrollToPosition.MakeVisible, true); }) }; Content = new StackLayout { Children = { endButton, endButtonAnimated, _listView } }; } } public class XamarinListViewScrollToBugPage3 : ContentPage { ListView _listView; ObservableCollection _collection = new ObservableCollection (); int _i =0; public XamarinListViewScrollToBugPage3 () { Title = "Scroll To in OnAppearing Uneven"; for (_i = 0; _i < 100; _i++) { var item = new ListObj { Name = string.Format ("{0} {0} {0} {0} {0} {0}", _i) }; _collection.Add (item); } var btnAdd = new Button { Text = "Add item", WidthRequest = 100 }; btnAdd.Clicked += BtnAddOnClicked; var btnBottom = new Button { Text = "Scroll to end", WidthRequest = 100 }; btnBottom.Clicked += BtnBottomOnClicked; var btnPanel = new StackLayout { Orientation = StackOrientation.Horizontal, HorizontalOptions = LayoutOptions.Center, Children = { btnAdd, btnBottom } }; _listView = new ListView { ItemsSource = _collection, BackgroundColor = Color.Transparent, VerticalOptions = LayoutOptions.FillAndExpand, HasUnevenRows = true, ItemTemplate = new DataTemplate (typeof(CellTemplateScrollToUneven)) }; _listView.TakePerformanceHit = true; _listView.ItemTapped += (sender, e) => ((ListView)sender).SelectedItem = null; _listView.AutomationId = "listView"; Content = new StackLayout { Children = { btnPanel, _listView } }; } protected override void OnAppearing () { base.OnAppearing (); _listView.ScrollTo (_collection.Last(), ScrollToPosition.MakeVisible, false); } void BtnBottomOnClicked(object sender, EventArgs e) { var item = _collection.Last(); _listView.ScrollTo(item, ScrollToPosition.End, true); } void BtnAddOnClicked(object sender, EventArgs eventArgs) { var str = string.Format("Item {0}", _i++); var item = new ListObj { Name = string.Format ("{0} {0} {0} {0} {0} {0}", _i) }; _collection.Add(item); _listView.ScrollTo(item, ScrollToPosition.End, true); } } }