From 900a0095c8417b258277ec146e9b1771213ba526 Mon Sep 17 00:00:00 2001 From: "Frank A. Krueger" Date: Wed, 25 Apr 2018 19:55:26 -0700 Subject: [PATCH] Reuse cell views in ListViews Fixes #132 --- Ooui.Forms/Cells/CellRenderer.cs | 12 +- Ooui.Forms/Extensions/ColorExtensions.cs | 7 + Ooui.Forms/Renderers/ListViewRenderer.cs | 156 ++++++++++++----------- Ooui/Client.js | 2 +- 4 files changed, 92 insertions(+), 85 deletions(-) diff --git a/Ooui.Forms/Cells/CellRenderer.cs b/Ooui.Forms/Cells/CellRenderer.cs index 2f3492f..ef7865a 100644 --- a/Ooui.Forms/Cells/CellRenderer.cs +++ b/Ooui.Forms/Cells/CellRenderer.cs @@ -14,7 +14,7 @@ namespace Ooui.Forms.Cells public virtual CellView GetCell(Cell item, CellView reusableView, List listView) { - var nativeCell = reusableView as CellView ?? GetCellInstance(item); + var nativeCell = reusableView ?? GetCellInstance (item); nativeCell.Cell = item; @@ -46,14 +46,12 @@ namespace Ooui.Forms.Cells protected void UpdateBackground(CellView tableViewCell, Cell cell) { - var defaultColor = Xamarin.Forms.Color.White.ToOouiColor(); - Color backgroundColor = defaultColor; + var backgroundColor = Xamarin.Forms.Color.Default; - if (cell.RealParent is VisualElement element) - backgroundColor = element.BackgroundColor == - Xamarin.Forms.Color.Default ? backgroundColor : element.BackgroundColor.ToOouiColor(); + if (backgroundColor == Xamarin.Forms.Color.Default && cell.RealParent is VisualElement element) + backgroundColor = element.BackgroundColor; - tableViewCell.Style.BackgroundColor = backgroundColor; + tableViewCell.Style.BackgroundColor = backgroundColor.ToOouiColor (Xamarin.Forms.Color.White); } protected void WireUpForceUpdateSizeRequested(Cell cell, CellView nativeCell) diff --git a/Ooui.Forms/Extensions/ColorExtensions.cs b/Ooui.Forms/Extensions/ColorExtensions.cs index 3fb59c2..f3bab76 100644 --- a/Ooui.Forms/Extensions/ColorExtensions.cs +++ b/Ooui.Forms/Extensions/ColorExtensions.cs @@ -23,5 +23,12 @@ namespace Ooui.Forms.Extensions return defaultColor.ToOouiColor (); return color.ToOouiColor (); } + + public static Color ToOouiColor (this Xamarin.Forms.Color color, Ooui.Color defaultColor) + { + if (color == Xamarin.Forms.Color.Default) + return defaultColor; + return color.ToOouiColor (); + } } } diff --git a/Ooui.Forms/Renderers/ListViewRenderer.cs b/Ooui.Forms/Renderers/ListViewRenderer.cs index 4b84e2f..b958f4c 100644 --- a/Ooui.Forms/Renderers/ListViewRenderer.cs +++ b/Ooui.Forms/Renderers/ListViewRenderer.cs @@ -5,40 +5,35 @@ using System.ComponentModel; using System.Linq; using Xamarin.Forms; using Xamarin.Forms.Internals; +using Ooui.Forms.Cells; namespace Ooui.Forms.Renderers { public class ListViewRenderer : ViewRenderer { private bool _disposed; - private List _listView; - private List _cells; - public ListViewRenderer() + public ListViewRenderer () { - _cells = new List(); } ITemplatedItemsView TemplatedItemsView => Element; - protected override void OnElementChanged(ElementChangedEventArgs e) + protected override void OnElementChanged (ElementChangedEventArgs e) { - if (e.OldElement != null) - { + if (e.OldElement != null) { var templatedItems = TemplatedItemsView.TemplatedItems; templatedItems.CollectionChanged -= OnCollectionChanged; e.OldElement.ScrollToRequested -= ListView_ScrollToRequested; } - if (e.NewElement != null) - { - if (Control == null) - { - _listView = new List(); - _listView.Style.Overflow = "scroll"; - _listView.Style.Padding = "0"; + if (e.NewElement != null) { + if (Control == null) { + var list = new List (); + list.Style.Overflow = "scroll"; + list.Style.Padding = "0"; - SetNativeControl(_listView); + SetNativeControl (list); } var templatedItems = TemplatedItemsView.TemplatedItems; @@ -46,31 +41,29 @@ namespace Ooui.Forms.Renderers e.NewElement.ScrollToRequested += ListView_ScrollToRequested; UpdateItems (); - UpdateBackgroundColor(); + UpdateBackgroundColor (); } - base.OnElementChanged(e); + base.OnElementChanged (e); } - protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) + protected override void OnElementPropertyChanged (object sender, PropertyChangedEventArgs e) { - base.OnElementPropertyChanged(sender, e); + base.OnElementPropertyChanged (sender, e); - if (e.PropertyName == ListView.ItemsSourceProperty.PropertyName) - UpdateItems(); + if (e.PropertyName == ItemsView.ItemsSourceProperty.PropertyName) + UpdateItems (); } - protected override void Dispose(bool disposing) + protected override void Dispose (bool disposing) { - UnsubscribeCellClicks(); + UnsubscribeCellClicks (); - base.Dispose(disposing); + base.Dispose (disposing); - if (disposing && !_disposed) - { + if (disposing && !_disposed) { - if (Element != null) - { + if (Element != null) { var templatedItems = TemplatedItemsView.TemplatedItems; templatedItems.CollectionChanged -= OnCollectionChanged; Element.ScrollToRequested -= ListView_ScrollToRequested; @@ -85,69 +78,76 @@ namespace Ooui.Forms.Renderers UpdateItems (); } - private void UnsubscribeCellClicks() - { - foreach (var c in _cells) - { - c.Click -= ListItem_Click; - } - } - - private void UpdateItems() + private void UnsubscribeCellClicks () { - UnsubscribeCellClicks(); - _cells.Clear(); - - foreach (var child in _listView.Children) - { - _listView.RemoveChild (child); + if (Control == null) + return; + foreach (var c in Control.Children) { + if (c is Element e) + e.Click -= ListItem_Click; } + } + + private void UpdateItems () + { + if (Control == null) + return; + + var listItems = Control.Children.OfType ().ToList (); var items = TemplatedItemsView.TemplatedItems; - if (!items.Any()) - { - return; + if (listItems.Count > items.Count) { + for (var i = items.Count; i < listItems.Count; i++) { + listItems[i].Click -= ListItem_Click; + Control.RemoveChild (listItems[i]); + } + listItems.RemoveRange (items.Count, listItems.Count - items.Count); + } + if (listItems.Count < items.Count) { + for (var i = listItems.Count; i < items.Count; i++) { + var li = new ListItem (); + li.Style["list-style-type"] = "none"; + li.Click += ListItem_Click; + Control.AppendChild (li); + listItems.Add (li); + } } bool grouping = Element.IsGroupingEnabled; - if (grouping) - { - return; + if (grouping) { + // Not Implemented } - - foreach (var item in items) - { - var cell = GetCell(item); - - var listItem = new ListItem(); - listItem.Style["list-style-type"] = "none"; - - listItem.AppendChild(cell); - listItem.Click += ListItem_Click; - - _cells.Add(listItem); - } - - foreach (var cell in _cells) - { - _listView.AppendChild(cell); + else { + var i = 0; + foreach (var item in items) { + var li = listItems[i]; + var children = li.Children; + var rv = children.Count > 0 ? children[0] as CellView : null; + var cell = GetCell (item, rv); + if (rv == null) { + li.AppendChild (cell); + } + i++; + } } } - private void ListItem_Click(object sender, TargetEventArgs e) + void ListItem_Click (object sender, TargetEventArgs e) { + if (Control == null) + return; var it = (ListItem)sender; - var ndx = _cells.IndexOf(it); - Element.NotifyRowTapped(ndx, null); + var ndx = Control.Children.IndexOf (it); + Element.NotifyRowTapped (ndx, null); } void ListView_ScrollToRequested (object sender, ScrollToRequestedEventArgs e) { if (Control == null) return; - + var oe = (ITemplatedItemsListScrollToRequestedEventArgs)e; var item = oe.Item; var group = oe.Group; @@ -161,19 +161,21 @@ namespace Ooui.Forms.Renderers } } - private void UpdateBackgroundColor() + void UpdateBackgroundColor () { - var backgroundColor = Element.BackgroundColor.ToOouiColor(); + if (Control == null) + return; + + var backgroundColor = Element.BackgroundColor.ToOouiColor (Xamarin.Forms.Color.White); - _listView.Style.BackgroundColor = backgroundColor; + Control.Style.BackgroundColor = backgroundColor; } - private Div GetCell(Cell cell) + CellView GetCell (Cell cell, CellView reusableView) { - var renderer = - (Cells.CellRenderer)Registrar.Registered.GetHandler(cell.GetType()); + var renderer = (Cells.CellRenderer)Registrar.Registered.GetHandlerForObject (cell); - var realCell = renderer.GetCell(cell, null, _listView); + var realCell = renderer.GetCell (cell, reusableView, Control); return realCell; } diff --git a/Ooui/Client.js b/Ooui/Client.js index 2534b79..c651674 100644 --- a/Ooui/Client.js +++ b/Ooui/Client.js @@ -1,6 +1,6 @@ // Ooui v1.0.0 -var debug = false; +var debug = true; const nodes = {}; const hasText = {};