Reuse cell views in ListViews

Fixes #132
This commit is contained in:
Frank A. Krueger 2018-04-25 19:55:26 -07:00
parent 8190f9103c
commit 900a0095c8
No known key found for this signature in database
GPG Key ID: 0471C67474FFE664
4 changed files with 92 additions and 85 deletions

View File

@ -14,7 +14,7 @@ namespace Ooui.Forms.Cells
public virtual CellView GetCell(Cell item, CellView reusableView, List listView) 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; nativeCell.Cell = item;
@ -46,14 +46,12 @@ namespace Ooui.Forms.Cells
protected void UpdateBackground(CellView tableViewCell, Cell cell) protected void UpdateBackground(CellView tableViewCell, Cell cell)
{ {
var defaultColor = Xamarin.Forms.Color.White.ToOouiColor(); var backgroundColor = Xamarin.Forms.Color.Default;
Color backgroundColor = defaultColor;
if (cell.RealParent is VisualElement element) if (backgroundColor == Xamarin.Forms.Color.Default && cell.RealParent is VisualElement element)
backgroundColor = element.BackgroundColor == backgroundColor = element.BackgroundColor;
Xamarin.Forms.Color.Default ? backgroundColor : element.BackgroundColor.ToOouiColor();
tableViewCell.Style.BackgroundColor = backgroundColor; tableViewCell.Style.BackgroundColor = backgroundColor.ToOouiColor (Xamarin.Forms.Color.White);
} }
protected void WireUpForceUpdateSizeRequested(Cell cell, CellView nativeCell) protected void WireUpForceUpdateSizeRequested(Cell cell, CellView nativeCell)

View File

@ -23,5 +23,12 @@ namespace Ooui.Forms.Extensions
return defaultColor.ToOouiColor (); return defaultColor.ToOouiColor ();
return color.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 ();
}
} }
} }

View File

@ -5,40 +5,35 @@ using System.ComponentModel;
using System.Linq; using System.Linq;
using Xamarin.Forms; using Xamarin.Forms;
using Xamarin.Forms.Internals; using Xamarin.Forms.Internals;
using Ooui.Forms.Cells;
namespace Ooui.Forms.Renderers namespace Ooui.Forms.Renderers
{ {
public class ListViewRenderer : ViewRenderer<ListView, List> public class ListViewRenderer : ViewRenderer<ListView, List>
{ {
private bool _disposed; private bool _disposed;
private List _listView;
private List<ListItem> _cells;
public ListViewRenderer() public ListViewRenderer ()
{ {
_cells = new List<ListItem>();
} }
ITemplatedItemsView<Cell> TemplatedItemsView => Element; ITemplatedItemsView<Cell> TemplatedItemsView => Element;
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e) protected override void OnElementChanged (ElementChangedEventArgs<ListView> e)
{ {
if (e.OldElement != null) if (e.OldElement != null) {
{
var templatedItems = TemplatedItemsView.TemplatedItems; var templatedItems = TemplatedItemsView.TemplatedItems;
templatedItems.CollectionChanged -= OnCollectionChanged; templatedItems.CollectionChanged -= OnCollectionChanged;
e.OldElement.ScrollToRequested -= ListView_ScrollToRequested; e.OldElement.ScrollToRequested -= ListView_ScrollToRequested;
} }
if (e.NewElement != null) if (e.NewElement != null) {
{ if (Control == null) {
if (Control == null) var list = new List ();
{ list.Style.Overflow = "scroll";
_listView = new List(); list.Style.Padding = "0";
_listView.Style.Overflow = "scroll";
_listView.Style.Padding = "0";
SetNativeControl(_listView); SetNativeControl (list);
} }
var templatedItems = TemplatedItemsView.TemplatedItems; var templatedItems = TemplatedItemsView.TemplatedItems;
@ -46,31 +41,29 @@ namespace Ooui.Forms.Renderers
e.NewElement.ScrollToRequested += ListView_ScrollToRequested; e.NewElement.ScrollToRequested += ListView_ScrollToRequested;
UpdateItems (); 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) if (e.PropertyName == ItemsView<Cell>.ItemsSourceProperty.PropertyName)
UpdateItems(); 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; var templatedItems = TemplatedItemsView.TemplatedItems;
templatedItems.CollectionChanged -= OnCollectionChanged; templatedItems.CollectionChanged -= OnCollectionChanged;
Element.ScrollToRequested -= ListView_ScrollToRequested; Element.ScrollToRequested -= ListView_ScrollToRequested;
@ -85,69 +78,76 @@ namespace Ooui.Forms.Renderers
UpdateItems (); UpdateItems ();
} }
private void UnsubscribeCellClicks() private void UnsubscribeCellClicks ()
{
foreach (var c in _cells)
{
c.Click -= ListItem_Click;
}
}
private void UpdateItems()
{ {
UnsubscribeCellClicks(); if (Control == null)
_cells.Clear(); return;
foreach (var c in Control.Children) {
foreach (var child in _listView.Children) if (c is Element e)
{ e.Click -= ListItem_Click;
_listView.RemoveChild (child);
} }
}
private void UpdateItems ()
{
if (Control == null)
return;
var listItems = Control.Children.OfType<ListItem> ().ToList ();
var items = TemplatedItemsView.TemplatedItems; var items = TemplatedItemsView.TemplatedItems;
if (!items.Any()) if (listItems.Count > items.Count) {
{ for (var i = items.Count; i < listItems.Count; i++) {
return; 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; bool grouping = Element.IsGroupingEnabled;
if (grouping) if (grouping) {
{ // Not Implemented
return;
} }
else {
foreach (var item in items) var i = 0;
{ foreach (var item in items) {
var cell = GetCell(item); var li = listItems[i];
var children = li.Children;
var listItem = new ListItem(); var rv = children.Count > 0 ? children[0] as CellView : null;
listItem.Style["list-style-type"] = "none"; var cell = GetCell (item, rv);
if (rv == null) {
listItem.AppendChild(cell); li.AppendChild (cell);
listItem.Click += ListItem_Click; }
i++;
_cells.Add(listItem); }
}
foreach (var cell in _cells)
{
_listView.AppendChild(cell);
} }
} }
private void ListItem_Click(object sender, TargetEventArgs e) void ListItem_Click (object sender, TargetEventArgs e)
{ {
if (Control == null)
return;
var it = (ListItem)sender; var it = (ListItem)sender;
var ndx = _cells.IndexOf(it); var ndx = Control.Children.IndexOf (it);
Element.NotifyRowTapped(ndx, null); Element.NotifyRowTapped (ndx, null);
} }
void ListView_ScrollToRequested (object sender, ScrollToRequestedEventArgs e) void ListView_ScrollToRequested (object sender, ScrollToRequestedEventArgs e)
{ {
if (Control == null) if (Control == null)
return; return;
var oe = (ITemplatedItemsListScrollToRequestedEventArgs)e; var oe = (ITemplatedItemsListScrollToRequestedEventArgs)e;
var item = oe.Item; var item = oe.Item;
var group = oe.Group; 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 = var renderer = (Cells.CellRenderer)Registrar.Registered.GetHandlerForObject<IRegisterable> (cell);
(Cells.CellRenderer)Registrar.Registered.GetHandler<IRegisterable>(cell.GetType());
var realCell = renderer.GetCell(cell, null, _listView); var realCell = renderer.GetCell (cell, reusableView, Control);
return realCell; return realCell;
} }

View File

@ -1,6 +1,6 @@
// Ooui v1.0.0 // Ooui v1.0.0
var debug = false; var debug = true;
const nodes = {}; const nodes = {};
const hasText = {}; const hasText = {};