diff options
Diffstat (limited to 'Xamarin.Forms.Platform.Android/Cells/ViewCellRenderer.cs')
-rw-r--r-- | Xamarin.Forms.Platform.Android/Cells/ViewCellRenderer.cs | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.Android/Cells/ViewCellRenderer.cs b/Xamarin.Forms.Platform.Android/Cells/ViewCellRenderer.cs new file mode 100644 index 00000000..4bf83395 --- /dev/null +++ b/Xamarin.Forms.Platform.Android/Cells/ViewCellRenderer.cs @@ -0,0 +1,178 @@ +using Android.Content; +using Android.Views; +using AView = Android.Views.View; + +namespace Xamarin.Forms.Platform.Android +{ + public class ViewCellRenderer : CellRenderer + { + protected override AView GetCellCore(Cell item, AView convertView, ViewGroup parent, Context context) + { + Performance.Start(); + var cell = (ViewCell)item; + + var container = convertView as ViewCellContainer; + if (container != null) + { + container.Update(cell); + Performance.Stop(); + return container; + } + + BindableProperty unevenRows = null, rowHeight = null; + if (ParentView is TableView) + { + unevenRows = TableView.HasUnevenRowsProperty; + rowHeight = TableView.RowHeightProperty; + } + else if (ParentView is ListView) + { + unevenRows = ListView.HasUnevenRowsProperty; + rowHeight = ListView.RowHeightProperty; + } + + IVisualElementRenderer view = Platform.CreateRenderer(cell.View); + Platform.SetRenderer(cell.View, view); + cell.View.IsPlatformEnabled = true; + var c = new ViewCellContainer(context, view, cell, ParentView, unevenRows, rowHeight); + + Performance.Stop(); + + return c; + } + + internal class ViewCellContainer : ViewGroup, INativeElementView + { + readonly View _parent; + readonly BindableProperty _rowHeight; + readonly BindableProperty _unevenRows; + IVisualElementRenderer _view; + ViewCell _viewCell; + + public ViewCellContainer(Context context, IVisualElementRenderer view, ViewCell viewCell, View parent, BindableProperty unevenRows, BindableProperty rowHeight) : base(context) + { + _view = view; + _parent = parent; + _unevenRows = unevenRows; + _rowHeight = rowHeight; + _viewCell = viewCell; + AddView(view.ViewGroup); + UpdateIsEnabled(); + } + + protected bool ParentHasUnevenRows + { + get { return (bool)_parent.GetValue(_unevenRows); } + } + + protected int ParentRowHeight + { + get { return (int)_parent.GetValue(_rowHeight); } + } + + public Element Element + { + get { return _viewCell; } + } + + public override bool OnInterceptTouchEvent(MotionEvent ev) + { + if (!Enabled) + return true; + return base.OnInterceptTouchEvent(ev); + } + + public void Update(ViewCell cell) + { + Performance.Start(); + + var renderer = GetChildAt(0) as IVisualElementRenderer; + var viewHandlerType = Registrar.Registered.GetHandlerType(cell.View.GetType()) ?? typeof(Platform.DefaultRenderer); + if (renderer != null && renderer.GetType() == viewHandlerType) + { + Performance.Start("Reuse"); + _viewCell = cell; + + cell.View.DisableLayout = true; + foreach (VisualElement c in cell.View.Descendants()) + c.DisableLayout = true; + + Performance.Start("Reuse.SetElement"); + renderer.SetElement(cell.View); + Performance.Stop("Reuse.SetElement"); + + Platform.SetRenderer(cell.View, _view); + + cell.View.DisableLayout = false; + foreach (VisualElement c in cell.View.Descendants()) + c.DisableLayout = false; + + var viewAsLayout = cell.View as Layout; + if (viewAsLayout != null) + viewAsLayout.ForceLayout(); + + Invalidate(); + + Performance.Stop("Reuse"); + Performance.Stop(); + return; + } + + RemoveView(_view.ViewGroup); + Platform.SetRenderer(_viewCell.View, null); + _viewCell.View.IsPlatformEnabled = false; + _view.ViewGroup.Dispose(); + + _viewCell = cell; + _view = Platform.CreateRenderer(_viewCell.View); + + Platform.SetRenderer(_viewCell.View, _view); + AddView(_view.ViewGroup); + + UpdateIsEnabled(); + + Performance.Stop(); + } + + public void UpdateIsEnabled() + { + Enabled = _viewCell.IsEnabled; + } + + protected override void OnLayout(bool changed, int l, int t, int r, int b) + { + Performance.Start(); + + double width = Context.FromPixels(r - l); + double height = Context.FromPixels(b - t); + + Performance.Start("Element.Layout"); + Xamarin.Forms.Layout.LayoutChildIntoBoundingRegion(_view.Element, new Rectangle(0, 0, width, height)); + Performance.Stop("Element.Layout"); + + _view.UpdateLayout(); + Performance.Stop(); + } + + protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) + { + Performance.Start(); + + int width = MeasureSpec.GetSize(widthMeasureSpec); + int height; + + if (ParentHasUnevenRows) + { + SizeRequest measure = _view.Element.Measure(Context.FromPixels(width), double.PositiveInfinity, MeasureFlags.IncludeMargins); + height = (int)Context.ToPixels(_viewCell.Height > 0 ? _viewCell.Height : measure.Request.Height); + } + else + height = (int)Context.ToPixels(ParentRowHeight == -1 ? BaseCellView.DefaultMinHeight : ParentRowHeight); + + SetMeasuredDimension(width, height); + + Performance.Stop(); + } + } + } +}
\ No newline at end of file |