ListViewRenderer now properly lays out custom cell views. As a result of this fix the renderer will now respect row heights set in Xamarin.Forms and should support lists with uneven cell heights.
This commit is contained in:
parent
a75d44b573
commit
fe75391962
|
@ -11,7 +11,17 @@ namespace Ooui.Forms.Renderers
|
|||
{
|
||||
public class ListViewRenderer : ViewRenderer<ListView, List>
|
||||
{
|
||||
const int DefaultRowHeight = 44;
|
||||
private bool _disposed;
|
||||
IVisualElementRenderer _prototype;
|
||||
|
||||
int _rowHeight;
|
||||
|
||||
public int RowHeight
|
||||
{
|
||||
get => _rowHeight;
|
||||
set => _rowHeight = value;
|
||||
}
|
||||
|
||||
public ListViewRenderer ()
|
||||
{
|
||||
|
@ -32,6 +42,10 @@ namespace Ooui.Forms.Renderers
|
|||
var list = new List ();
|
||||
list.Style.Overflow = "scroll";
|
||||
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);
|
||||
}
|
||||
|
@ -40,6 +54,8 @@ namespace Ooui.Forms.Renderers
|
|||
templatedItems.CollectionChanged += OnCollectionChanged;
|
||||
e.NewElement.ScrollToRequested += ListView_ScrollToRequested;
|
||||
|
||||
UpdateRowHeight();
|
||||
|
||||
UpdateItems ();
|
||||
UpdateBackgroundColor ();
|
||||
}
|
||||
|
@ -121,11 +137,22 @@ namespace Ooui.Forms.Renderers
|
|||
}
|
||||
else {
|
||||
var i = 0;
|
||||
double offset = 0;
|
||||
foreach (var item in items) {
|
||||
var li = listItems[i];
|
||||
var nativeCell = items[i];
|
||||
var children = li.Children;
|
||||
var rv = children.Count > 0 ? children[0] as CellElement : null;
|
||||
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) {
|
||||
li.AppendChild (cell);
|
||||
}
|
||||
|
@ -161,6 +188,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 ()
|
||||
{
|
||||
if (Control == null)
|
||||
|
|
Loading…
Reference in New Issue