summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRui Marinho <me@ruimarinho.net>2016-06-09 18:59:26 +0100
committerSamantha Houts <samantha@teamredwall.com>2016-06-09 10:59:26 -0700
commite2e303654e76eaf79fa4b1629df1f2b351fa9fcd (patch)
tree8c51b29c5511dece0bf28794a8f225e8c563d6b1
parent67511ed858719ce8906929f7900e9c1080cd48d9 (diff)
downloadxamarin-forms-e2e303654e76eaf79fa4b1629df1f2b351fa9fcd.tar.gz
xamarin-forms-e2e303654e76eaf79fa4b1629df1f2b351fa9fcd.tar.bz2
xamarin-forms-e2e303654e76eaf79fa4b1629df1f2b351fa9fcd.zip
[Android] Always create a new cell for GroupHeader when using Recycling (#206)
* [Android] Always create a new cell for GroupHeader when using RecycleElement * [iOS] Fix uitest iOS * [Android] Fix test on android
-rw-r--r--Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40704.cs231
-rw-r--r--Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems1
-rw-r--r--Xamarin.Forms.Platform.Android/Renderers/ListViewAdapter.cs15
3 files changed, 246 insertions, 1 deletions
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40704.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40704.cs
new file mode 100644
index 00000000..dcae4617
--- /dev/null
+++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla40704.cs
@@ -0,0 +1,231 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using Xamarin.Forms.CustomAttributes;
+using Xamarin.Forms.Internals;
+using System.Text;
+
+#if UITEST
+using Xamarin.UITest;
+using NUnit.Framework;
+#endif
+
+namespace Xamarin.Forms.Controls
+{
+ [Preserve(AllMembers = true)]
+ [Issue(IssueTracker.Bugzilla, 40704, "Strange duplication of listview headers when collapsing/expanding sections")]
+ public class Bugzilla40704 : TestContentPage // or TestMasterDetailPage, etc ...
+ {
+ ListView listview;
+ int count = 2;
+
+ protected override void Init()
+ {
+ listview = new ListView(ListViewCachingStrategy.RecycleElement)
+ {
+ AutomationId = "lstMain",
+ IsGroupingEnabled = true,
+ HasUnevenRows = true,
+ GroupHeaderTemplate = new DataTemplate(typeof(GroupHeaderViewCell)),
+ ItemTemplate = new DataTemplate(typeof(ItemTestViewCell))
+ };
+
+ FillPatientsList();
+
+ var button = new Button()
+ {
+ Text = "Collapse",
+ AutomationId = "btnCollappse"
+ };
+ listview.Footer = button;
+ button.Clicked += Button_Clicked;
+ Content = listview;
+ }
+
+ void Button_Clicked(object sender, EventArgs e)
+ {
+ var source = listview.ItemsSource as List<PatientsGroupViewModel>;
+ source[count].Toggle();
+ count--;
+ if (count < 0)
+ count = 2;
+ }
+
+ private void FillPatientsList()
+ {
+ const int groupsNumber = 3;
+ const int patientsNumber = 10;
+
+ var patientGroups = new List<PatientsGroupViewModel>();
+ var random = new Random();
+
+ for (var i = 0; i < groupsNumber; i++)
+ {
+ var patients = new List<PatientViewModel>();
+ for (var j = 0; j < patientsNumber; j++)
+ {
+ var code = string.Format("{0}-{1}", i, j);
+ var length = random.Next(5, 100);
+ var strBuilder = new StringBuilder();
+ for (int z = 0; z < length; z++)
+ {
+ strBuilder.Append(code);
+ if (z % 7 == 0)
+ {
+ strBuilder.Append(' ');
+ }
+ }
+
+ patients.Add(new PatientViewModel(code) { Description = strBuilder.ToString() });
+ }
+
+ patientGroups.Add(new PatientsGroupViewModel(patients)
+ {
+ Title = "Menu - " + i.ToString()
+ });
+
+ }
+
+ listview.ItemsSource = patientGroups;
+ }
+
+ [Preserve(AllMembers = true)]
+ public class GroupHeaderViewCell : ViewCell
+ {
+ TapGestureRecognizer tapGesture;
+
+ public GroupHeaderViewCell()
+ {
+ Height = 40;
+ var grd = new Grid { BackgroundColor = Color.Aqua, Padding = new Thickness(5, 10) };
+ tapGesture = new TapGestureRecognizer();
+ tapGesture.Tapped += HeaderCell_OnTapped;
+ grd.GestureRecognizers.Add(tapGesture);
+ var lbl = new Label { HorizontalOptions = LayoutOptions.FillAndExpand, TextColor = Color.Black, FontSize = 16 };
+ lbl.SetBinding(Label.TextProperty, new Binding("Title"));
+
+ grd.Children.Add(lbl);
+ View = grd;
+ }
+
+ void HeaderCell_OnTapped(object sender, EventArgs e)
+ {
+ var cell = (Layout)sender;
+ var vm = cell.BindingContext as PatientsGroupViewModel;
+
+ if (vm != null)
+ {
+ vm.Toggle();
+ }
+ }
+ }
+
+ [Preserve(AllMembers = true)]
+ public class ItemTestViewCell : ViewCell
+ {
+ public ItemTestViewCell()
+ {
+
+ var grd = new Grid { BackgroundColor = Color.Yellow };
+ var lbl = new Label { HorizontalOptions = LayoutOptions.FillAndExpand, TextColor = Color.Black, FontSize = 16, LineBreakMode = LineBreakMode.WordWrap };
+ lbl.SetBinding(Label.TextProperty, new Binding("Description"));
+ grd.Children.Add(lbl);
+ View = grd;
+ }
+ }
+
+ [Preserve(AllMembers = true)]
+ public class RangeObservableCollection<T> : ObservableCollection<T>
+ {
+ private bool _suppressNotification = false;
+
+ protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
+ {
+ if (!_suppressNotification)
+ base.OnCollectionChanged(e);
+ }
+
+ public void AddRange(IEnumerable<T> list)
+ {
+ if (list == null)
+ throw new ArgumentNullException("list");
+
+ _suppressNotification = true;
+
+ foreach (var item in list)
+ {
+ Add(item);
+ }
+ _suppressNotification = false;
+ OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
+ }
+ }
+
+ [Preserve(AllMembers = true)]
+ public class PatientsGroupViewModel : RangeObservableCollection<PatientViewModel>
+ {
+ public bool IsCollapsed { get; private set; }
+
+ public string Title { get; set; }
+
+ private readonly List<PatientViewModel> _patients;
+
+ public PatientsGroupViewModel(List<PatientViewModel> patients)
+ {
+ _patients = patients;
+
+ UpdateCollection();
+ }
+
+ public void Toggle()
+ {
+ IsCollapsed = !IsCollapsed;
+
+ UpdateCollection();
+ }
+
+ private void UpdateCollection()
+ {
+ if (!IsCollapsed)
+ {
+ AddRange(_patients);
+ }
+ else
+ {
+ Clear();
+ }
+ }
+ }
+
+ [Preserve(AllMembers = true)]
+ public class PatientViewModel
+ {
+ public PatientViewModel(string code)
+ {
+ Code = code;
+ }
+
+ public string Code { get; set; }
+
+ public string Description { get; set; }
+ }
+
+
+ #if UITEST
+ [Test]
+ public void Bugzilla40704Test()
+ {
+ RunningApp.ScrollDownTo("btnCollappse", "lstMain", ScrollStrategy.Gesture, 0.8, timeout: TimeSpan.FromMinutes(2));
+ RunningApp.Tap("btnCollappse");
+ RunningApp.ScrollDownTo("btnCollappse", "lstMain", ScrollStrategy.Gesture, 0.8, timeout: TimeSpan.FromMinutes(2));
+ RunningApp.Tap("btnCollappse");
+ RunningApp.ScrollDownTo("btnCollappse", "lstMain", ScrollStrategy.Gesture, 0.8, timeout: TimeSpan.FromMinutes(2));
+ RunningApp.Tap("btnCollappse");
+ RunningApp.WaitForElement("Menu - 2");
+ RunningApp.WaitForElement("Menu - 1");
+ RunningApp.WaitForElement("Menu - 0");
+ }
+#endif
+ }
+}
diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
index 991270b6..00fad875 100644
--- a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
+++ b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
@@ -403,6 +403,7 @@
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla39963.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla39987.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Bugzilla40704.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla22229.xaml">
diff --git a/Xamarin.Forms.Platform.Android/Renderers/ListViewAdapter.cs b/Xamarin.Forms.Platform.Android/Renderers/ListViewAdapter.cs
index 81214957..522ff4b2 100644
--- a/Xamarin.Forms.Platform.Android/Renderers/ListViewAdapter.cs
+++ b/Xamarin.Forms.Platform.Android/Renderers/ListViewAdapter.cs
@@ -421,7 +421,20 @@ namespace Xamarin.Forms.Platform.Android
if (global == position || cells.Count > 0)
{
- cells.Add(group.HeaderContent);
+ if (_listView.CachingStrategy == ListViewCachingStrategy.RecycleElement)
+ {
+ var groupContent = _listView.TemplatedItems.GroupHeaderTemplate.CreateContent(group.ItemsSource, _listView) as Cell;
+ if (groupContent != null)
+ {
+ groupContent.BindingContext = group.ItemsSource;
+ cells.Add(groupContent);
+ }
+ }
+ else
+ {
+ cells.Add(group.HeaderContent);
+ }
+
if (cells.Count == take)
return cells;
}