Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit f568ae2

Browse files
committed
[Android] Handle creating a default GroupHeader if no GroupHeaderTemplate is provided (#248)
1 parent 7e65138 commit f568ae2

File tree

3 files changed

+113
-15
lines changed

3 files changed

+113
-15
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System;
2+
using System.Collections.ObjectModel;
3+
using Xamarin.Forms.CustomAttributes;
4+
using Xamarin.Forms.Internals;
5+
6+
#if UITEST
7+
using Xamarin.UITest;
8+
using NUnit.Framework;
9+
#endif
10+
11+
namespace Xamarin.Forms.Controls
12+
{
13+
[Preserve(AllMembers = true)]
14+
[Issue(IssueTracker.None, 55555, "Header problem")]
15+
public class Issue55555 : TestContentPage // or TestMasterDetailPage, etc ...
16+
{
17+
protected override void Init()
18+
{
19+
var lstView = new ListView(ListViewCachingStrategy.RecycleElement);
20+
ObservableCollection<GroupedVeggieModel> grouped = CreateData();
21+
22+
lstView.ItemsSource = grouped;
23+
lstView.HasUnevenRows = true;
24+
lstView.IsGroupingEnabled = true;
25+
lstView.GroupDisplayBinding = new Binding("LongName");
26+
lstView.GroupShortNameBinding = new Binding("ShortName");
27+
28+
lstView.ItemTemplate = new DataTemplate(typeof(DemoTextCell));
29+
lstView.ItemTemplate.SetBinding(DemoTextCell.TextProperty, "Name");
30+
31+
Content = lstView;
32+
}
33+
34+
static ObservableCollection<GroupedVeggieModel> CreateData()
35+
{
36+
var grouped = new ObservableCollection<GroupedVeggieModel>();
37+
38+
var veggieGroup = new GroupedVeggieModel() { LongName = "vegetables", ShortName = "v" };
39+
veggieGroup.Add(new VeggieModel() { Name = "celery", IsReallyAVeggie = true, Comment = "try ants on a log" });
40+
veggieGroup.Add(new VeggieModel() { Name = "tomato", IsReallyAVeggie = false, Comment = "pairs well with basil" });
41+
veggieGroup.Add(new VeggieModel() { Name = "zucchini", IsReallyAVeggie = true, Comment = "zucchini bread > bannana bread" });
42+
veggieGroup.Add(new VeggieModel() { Name = "peas", IsReallyAVeggie = true, Comment = "like peas in a pod" });
43+
44+
var fruitGroup = new GroupedVeggieModel() { LongName = "fruit", ShortName = "f" };
45+
fruitGroup.Add(new VeggieModel() { Name = "banana", IsReallyAVeggie = false, Comment = "available in chip form factor" });
46+
fruitGroup.Add(new VeggieModel() { Name = "strawberry", IsReallyAVeggie = false, Comment = "spring plant" });
47+
fruitGroup.Add(new VeggieModel() { Name = "cherry", IsReallyAVeggie = false, Comment = "topper for icecream" });
48+
49+
grouped.Add(veggieGroup);
50+
grouped.Add(fruitGroup);
51+
52+
return grouped;
53+
}
54+
55+
[Preserve(AllMembers = true)]
56+
public class VeggieModel
57+
{
58+
public string Name { get; set; }
59+
public string Comment { get; set; }
60+
public bool IsReallyAVeggie { get; set; }
61+
public string Image { get; set; }
62+
}
63+
64+
[Preserve(AllMembers = true)]
65+
public class GroupedVeggieModel : ObservableCollection<VeggieModel>
66+
{
67+
public string LongName { get; set; }
68+
public string ShortName { get; set; }
69+
}
70+
71+
[Preserve(AllMembers = true)]
72+
public class DemoTextCell : TextCell
73+
{
74+
public DemoTextCell()
75+
{
76+
Height = 150;
77+
}
78+
}
79+
80+
#if UITEST
81+
[Test]
82+
public void TGroupDisplayBindingPresentRecycleElementTest()
83+
{
84+
RunningApp.WaitForElement(q => q.Marked("vegetables"));
85+
}
86+
#endif
87+
}
88+
}

Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@
410410
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla41038.cs" />
411411
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla38284.cs" />
412412
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla39486.cs" />
413+
<Compile Include="$(MSBuildThisFileDirectory)Issue55555.cs" />
413414
</ItemGroup>
414415
<ItemGroup>
415416
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla22229.xaml">

Xamarin.Forms.Platform.Android/Renderers/ListViewAdapter.cs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ public override AView GetView(int position, AView convertView, ViewGroup parent)
199199

200200
if (cachingStrategy == ListViewCachingStrategy.RecycleElement && convertView != null)
201201
{
202-
var boxedCell = (INativeElementView)convertView;
202+
var boxedCell = convertView as INativeElementView;
203203
if (boxedCell == null)
204204
{
205205
throw new InvalidOperationException($"View for cell must implement {nameof(INativeElementView)} to enable recycling.");
@@ -403,20 +403,9 @@ List<Cell> GetCellsFromPosition(int position, int take)
403403

404404
if (global == position || cells.Count > 0)
405405
{
406-
if (_listView.CachingStrategy == ListViewCachingStrategy.RecycleElement)
407-
{
408-
var groupContent = _listView.TemplatedItems.GroupHeaderTemplate?.CreateContent(group.ItemsSource, _listView) as Cell;
409-
if (groupContent != null)
410-
{
411-
groupContent.Parent = _listView;
412-
groupContent.BindingContext = group.ItemsSource;
413-
cells.Add(groupContent);
414-
}
415-
}
416-
else
417-
{
418-
cells.Add(group.HeaderContent);
419-
}
406+
//Always create a new cell if we are using the RecycleElement strategy
407+
var headerCell = _listView.CachingStrategy == ListViewCachingStrategy.RecycleElement ? GetNewGroupHeaderCell(group) : group.HeaderContent;
408+
cells.Add(headerCell);
420409

421410
if (cells.Count == take)
422411
return cells;
@@ -565,6 +554,26 @@ void UpdateSeparatorColor(bool isHeader, AView bline)
565554
}
566555
}
567556

557+
Cell GetNewGroupHeaderCell(ITemplatedItemsList<Cell> group)
558+
{
559+
var groupHeaderCell = _listView.TemplatedItems.GroupHeaderTemplate?.CreateContent(group.ItemsSource, _listView) as Cell;
560+
561+
if (groupHeaderCell != null)
562+
{
563+
groupHeaderCell.BindingContext = group.ItemsSource;
564+
}
565+
else
566+
{
567+
groupHeaderCell = new TextCell();
568+
groupHeaderCell.SetBinding(TextCell.TextProperty, nameof(group.Name));
569+
groupHeaderCell.BindingContext = group;
570+
}
571+
572+
groupHeaderCell.Parent = _listView;
573+
groupHeaderCell.SetIsGroupHeader<ItemsView<Cell>, Cell>(true);
574+
return groupHeaderCell;
575+
}
576+
568577
enum CellType
569578
{
570579
Row,

0 commit comments

Comments
 (0)