Merge pull request #207 from zumero/listview-subviews
Fixing layouts of Ooui.Forms ViewCells
This commit is contained in:
commit
7fdefa5a58
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Timers;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using Xamarin.Forms.Internals;
|
using Xamarin.Forms.Internals;
|
||||||
using Ooui.Forms.Cells;
|
using Ooui.Forms.Cells;
|
||||||
|
@ -11,7 +12,18 @@ namespace Ooui.Forms.Renderers
|
||||||
{
|
{
|
||||||
public class ListViewRenderer : ViewRenderer<ListView, List>
|
public class ListViewRenderer : ViewRenderer<ListView, List>
|
||||||
{
|
{
|
||||||
|
const int DefaultRowHeight = 44;
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
IVisualElementRenderer _prototype;
|
||||||
|
Timer _timer;
|
||||||
|
|
||||||
|
int _rowHeight;
|
||||||
|
|
||||||
|
public int RowHeight
|
||||||
|
{
|
||||||
|
get => _rowHeight;
|
||||||
|
set => _rowHeight = value;
|
||||||
|
}
|
||||||
|
|
||||||
public ListViewRenderer ()
|
public ListViewRenderer ()
|
||||||
{
|
{
|
||||||
|
@ -32,6 +44,10 @@ namespace Ooui.Forms.Renderers
|
||||||
var list = new List ();
|
var list = new List ();
|
||||||
list.Style.Overflow = "scroll";
|
list.Style.Overflow = "scroll";
|
||||||
list.Style.Padding = "0";
|
list.Style.Padding = "0";
|
||||||
|
// Make the list element positioned so child elements will
|
||||||
|
// be positioned relative to it. This will allow the list
|
||||||
|
// to scroll properly.
|
||||||
|
list.Style.Position = "relative";
|
||||||
|
|
||||||
SetNativeControl (list);
|
SetNativeControl (list);
|
||||||
}
|
}
|
||||||
|
@ -40,6 +56,8 @@ namespace Ooui.Forms.Renderers
|
||||||
templatedItems.CollectionChanged += OnCollectionChanged;
|
templatedItems.CollectionChanged += OnCollectionChanged;
|
||||||
e.NewElement.ScrollToRequested += ListView_ScrollToRequested;
|
e.NewElement.ScrollToRequested += ListView_ScrollToRequested;
|
||||||
|
|
||||||
|
UpdateRowHeight();
|
||||||
|
|
||||||
UpdateItems ();
|
UpdateItems ();
|
||||||
UpdateSeparator ();
|
UpdateSeparator ();
|
||||||
UpdateBackgroundColor ();
|
UpdateBackgroundColor ();
|
||||||
|
@ -54,6 +72,29 @@ namespace Ooui.Forms.Renderers
|
||||||
|
|
||||||
if (e.PropertyName == ItemsView<Cell>.ItemsSourceProperty.PropertyName)
|
if (e.PropertyName == ItemsView<Cell>.ItemsSourceProperty.PropertyName)
|
||||||
UpdateItems();
|
UpdateItems();
|
||||||
|
else if (e.PropertyName == Xamarin.Forms.ListView.RowHeightProperty.PropertyName)
|
||||||
|
{
|
||||||
|
UpdateRowHeight();
|
||||||
|
UpdateItems();
|
||||||
|
}
|
||||||
|
else if (e.PropertyName == VisualElement.WidthProperty.PropertyName)
|
||||||
|
{
|
||||||
|
if (_timer != null)
|
||||||
|
{
|
||||||
|
_timer.Stop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_timer = new Timer();
|
||||||
|
_timer.Interval = 250;
|
||||||
|
_timer.Elapsed += delegate {
|
||||||
|
UpdateItems();
|
||||||
|
};
|
||||||
|
_timer.Enabled = true;
|
||||||
|
_timer.AutoReset = false;
|
||||||
|
}
|
||||||
|
_timer.Start();
|
||||||
|
}
|
||||||
else if (e.PropertyName == Xamarin.Forms.ListView.SeparatorColorProperty.PropertyName)
|
else if (e.PropertyName == Xamarin.Forms.ListView.SeparatorColorProperty.PropertyName)
|
||||||
UpdateSeparator ();
|
UpdateSeparator ();
|
||||||
else if (e.PropertyName == Xamarin.Forms.ListView.SeparatorVisibilityProperty.PropertyName)
|
else if (e.PropertyName == Xamarin.Forms.ListView.SeparatorVisibilityProperty.PropertyName)
|
||||||
|
@ -68,6 +109,8 @@ namespace Ooui.Forms.Renderers
|
||||||
|
|
||||||
if (disposing && !_disposed) {
|
if (disposing && !_disposed) {
|
||||||
|
|
||||||
|
ClearPrototype();
|
||||||
|
|
||||||
if (Element != null) {
|
if (Element != null) {
|
||||||
var templatedItems = TemplatedItemsView.TemplatedItems;
|
var templatedItems = TemplatedItemsView.TemplatedItems;
|
||||||
templatedItems.CollectionChanged -= OnCollectionChanged;
|
templatedItems.CollectionChanged -= OnCollectionChanged;
|
||||||
|
@ -78,6 +121,17 @@ namespace Ooui.Forms.Renderers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClearPrototype()
|
||||||
|
{
|
||||||
|
if (_prototype != null)
|
||||||
|
{
|
||||||
|
var element = _prototype.Element;
|
||||||
|
element?.ClearValue(Platform.RendererProperty);
|
||||||
|
_prototype?.Dispose();
|
||||||
|
_prototype = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void OnCollectionChanged (object sender, NotifyCollectionChangedEventArgs e)
|
private void OnCollectionChanged (object sender, NotifyCollectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
UpdateItems ();
|
UpdateItems ();
|
||||||
|
@ -127,11 +181,22 @@ namespace Ooui.Forms.Renderers
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var i = 0;
|
var i = 0;
|
||||||
|
double offset = 0;
|
||||||
foreach (var item in items) {
|
foreach (var item in items) {
|
||||||
var li = listItems[i];
|
var li = listItems[i];
|
||||||
|
var nativeCell = items[i];
|
||||||
var children = li.Children;
|
var children = li.Children;
|
||||||
var rv = children.Count > 0 ? children[0] as CellElement : null;
|
var rv = children.Count > 0 ? children[0] as CellElement : null;
|
||||||
var cell = GetCell (item, rv);
|
var cell = GetCell (item, rv);
|
||||||
|
var height = CalculateHeightForCell(nativeCell);
|
||||||
|
li.Style.Height = height;
|
||||||
|
var viewCell = (ViewCell)cell.Cell;
|
||||||
|
if (viewCell != null && viewCell.View != null)
|
||||||
|
{
|
||||||
|
var rect = new Rectangle(0, offset, Element.Width, height);
|
||||||
|
Layout.LayoutChildIntoBoundingRegion(viewCell.View, rect);
|
||||||
|
}
|
||||||
|
offset += height;
|
||||||
if (rv == null) {
|
if (rv == null) {
|
||||||
li.AppendChild (cell);
|
li.AppendChild (cell);
|
||||||
}
|
}
|
||||||
|
@ -188,6 +253,56 @@ namespace Ooui.Forms.Renderers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateRowHeight()
|
||||||
|
{
|
||||||
|
var rowHeight = Element.RowHeight;
|
||||||
|
if (Element.HasUnevenRows && rowHeight == -1)
|
||||||
|
RowHeight = -1;
|
||||||
|
else
|
||||||
|
RowHeight = rowHeight <= 0 ? DefaultRowHeight : rowHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal double CalculateHeightForCell(Cell cell)
|
||||||
|
{
|
||||||
|
if (!Element.HasUnevenRows)
|
||||||
|
{
|
||||||
|
return RowHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var viewCell = cell as ViewCell;
|
||||||
|
if (viewCell != null && viewCell.View != null)
|
||||||
|
{
|
||||||
|
var target = viewCell.View;
|
||||||
|
if (_prototype == null)
|
||||||
|
_prototype = Platform.CreateRenderer(target);
|
||||||
|
else
|
||||||
|
_prototype.SetElement(target);
|
||||||
|
|
||||||
|
Platform.SetRenderer(target, _prototype);
|
||||||
|
|
||||||
|
var req = target.Measure(Element.Width, double.PositiveInfinity, MeasureFlags.IncludeMargins);
|
||||||
|
|
||||||
|
target.ClearValue(Platform.RendererProperty);
|
||||||
|
foreach (Xamarin.Forms.Element descendant in target.Descendants())
|
||||||
|
{
|
||||||
|
IVisualElementRenderer renderer = Platform.GetRenderer(descendant as VisualElement);
|
||||||
|
|
||||||
|
// Clear renderer from descendent; this will not happen in Dispose as normal because we need to
|
||||||
|
// unhook the Element from the renderer before disposing it.
|
||||||
|
descendant.ClearValue(Platform.RendererProperty);
|
||||||
|
renderer?.Dispose();
|
||||||
|
renderer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var height = req.Request.Height;
|
||||||
|
return height > 1 ? height : DefaultRowHeight;
|
||||||
|
}
|
||||||
|
var renderHeight = cell.RenderHeight;
|
||||||
|
return renderHeight > 0 ? renderHeight : DefaultRowHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateBackgroundColor ()
|
void UpdateBackgroundColor ()
|
||||||
{
|
{
|
||||||
if (Control == null)
|
if (Control == null)
|
||||||
|
|
Loading…
Reference in New Issue