Skip to content

Commit

Permalink
Fix cell parenting when using Retain Caching (#4636)
Browse files Browse the repository at this point in the history
  • Loading branch information
PureWeen authored Feb 14, 2022
1 parent 38234b2 commit 67bc44d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ internal class ListViewAdapter : CellAdapter
protected readonly ListView _listView;
readonly AListView _realListView;
readonly Dictionary<DataTemplate, int> _templateToId = new Dictionary<DataTemplate, int>();
readonly List<ConditionalFocusLayout> _layoutsCreated = new List<ConditionalFocusLayout>();
readonly Dictionary<int, ConditionalFocusLayout> _layoutsCreated = new Dictionary<int, ConditionalFocusLayout>();
int _dataTemplateIncrementer = 2; // lets start at not 0 because ...

// We will use _dataTemplateIncrementer to get the proper ViewType key for the item's DataTemplate and store these keys in _templateToId.
Expand Down Expand Up @@ -244,10 +244,23 @@ public override AView GetView(int position, AView convertView, ViewGroup parent)
}
else
{
layout = new ConditionalFocusLayout(_context) { Orientation = Orientation.Vertical };
_layoutsCreated.Add(layout);
// This means the cell was already created during the measuring phase
// so we just reuse the layout already created for the cell
// This only ever happens if the ListView is forced to measure itself because
// it has infinite height
if (convertView == null && cell.Handler?.NativeView is AView aView &&
aView.Parent is ConditionalFocusLayout cfl)
{
layout = cfl;
}
else
{
layout = new ConditionalFocusLayout(_context) { Orientation = Orientation.Vertical };
_layoutsCreated[position] = layout;
}
}


if (((cachingStrategy & ListViewCachingStrategy.RecycleElement) != 0) && convertView != null)
{
var boxedCell = convertView as INativeElementView;
Expand Down Expand Up @@ -310,7 +323,12 @@ public override AView GetView(int position, AView convertView, ViewGroup parent)
}
}
else
layout.AddView(view, 0);
{
if (view.Parent != layout)
{
layout.AddView(view, 0);
}
}

Performance.Stop(reference, "AddView");

Expand Down Expand Up @@ -493,11 +511,9 @@ protected override void HandleItemClick(AdapterView parent, AView view, int posi

void DisposeCells()
{
var cellCount = _layoutsCreated.Count;

for (int i = 0; i < cellCount; i++)
foreach(var key in _layoutsCreated)
{
var layout = _layoutsCreated[i];
var layout = key.Value;

if (layout.IsDisposed())
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,15 @@ public override Size GetDesiredSize(double widthConstraint, double heightConstra
continue;
}

AView listItem = _adapter.GetView(i, null, Control);
// If the parent is already set then we'll just pass
// that in as the convert view so that GetView doesn't create
// an additional ConditionalFocusLayout
// We're basically faking re-use to the GetView call
AView currentParent = null;
if(cell.Handler?.NativeView is AView aView)
currentParent = aView.Parent as AView;

AView listItem = _adapter.GetView(i, currentParent, Control);
int widthSpec;

if (double.IsInfinity(widthConstraint))
Expand Down

0 comments on commit 67bc44d

Please sign in to comment.