public override AView GetView(int position, AView convertView, ViewGroup parent) { Cell cell = null; Performance.Start(); ListViewCachingStrategy cachingStrategy = Controller.CachingStrategy; var nextCellIsHeader = false; if (cachingStrategy == ListViewCachingStrategy.RetainElement || convertView == null) { if (_listView.IsGroupingEnabled) { List <Cell> cells = GetCellsFromPosition(position, 2); if (cells.Count > 0) { cell = cells[0]; } if (cells.Count == 2) { nextCellIsHeader = cells[1].GetIsGroupHeader <ItemsView <Cell>, Cell>(); } } if (cell == null) { cell = GetCellForPosition(position); if (cell == null) { return(new AView(_context)); } } } var cellIsBeingReused = false; var layout = convertView as ConditionalFocusLayout; if (layout != null) { cellIsBeingReused = true; convertView = layout.GetChildAt(0); } else { layout = new ConditionalFocusLayout(_context) { Orientation = Orientation.Vertical } }; if (cachingStrategy == ListViewCachingStrategy.RecycleElement && convertView != null) { var boxedCell = convertView as INativeElementView; if (boxedCell == null) { throw new InvalidOperationException($"View for cell must implement {nameof(INativeElementView)} to enable recycling."); } cell = (Cell)boxedCell.Element; // We are going to re-set the Platform here because in some cases (headers mostly) its possible this is unset and // when the binding context gets updated the measure passes will all fail. By applying this here the Update call // further down will result in correct layouts. cell.Platform = _listView.Platform; ICellController cellController = cell; cellController.SendDisappearing(); int row = position; var group = 0; var templatedItems = TemplatedItemsView.TemplatedItems; if (_listView.IsGroupingEnabled) { group = templatedItems.GetGroupIndexFromGlobal(position, out row); } var templatedList = templatedItems.GetGroup(group); if (_listView.IsGroupingEnabled) { if (row == 0) { templatedList.UpdateHeader(cell, group); } else { templatedList.UpdateContent(cell, row - 1); } } else { templatedList.UpdateContent(cell, row); } cellController.SendAppearing(); if (cell.BindingContext == ActionModeObject) { ActionModeContext = cell; ContextView = layout; } if (ReferenceEquals(_listView.SelectedItem, cell.BindingContext)) { Select(_listView.IsGroupingEnabled ? row - 1 : row, layout); } else if (cell.BindingContext == ActionModeObject) { SetSelectedBackground(layout, true); } else { UnsetSelectedBackground(layout); } Performance.Stop(); return(layout); } AView view = CellFactory.GetCell(cell, convertView, parent, _context, _listView); Performance.Start("AddView"); if (cellIsBeingReused) { if (convertView != view) { layout.RemoveViewAt(0); layout.AddView(view, 0); } } else { layout.AddView(view, 0); } Performance.Stop("AddView"); bool isHeader = cell.GetIsGroupHeader <ItemsView <Cell>, Cell>(); AView bline; UpdateSeparatorVisibility(cell, cellIsBeingReused, isHeader, nextCellIsHeader, layout, out bline); UpdateSeparatorColor(isHeader, bline); if ((bool)cell.GetValue(IsSelectedProperty)) { Select(position, layout); } else { UnsetSelectedBackground(layout); } layout.ApplyTouchListenersToSpecialCells(cell); Performance.Stop(); return(layout); }
public override AView GetView(int position, AView convertView, ViewGroup parent) { Cell cell = null; Performance.Start(out string reference); ListViewCachingStrategy cachingStrategy = Controller.CachingStrategy; var nextCellIsHeader = false; if (cachingStrategy == ListViewCachingStrategy.RetainElement || convertView == null) { if (_listView.IsGroupingEnabled) { List <Cell> cells = GetCellsFromPosition(position, 2); if (cells.Count > 0) { cell = cells[0]; } if (cells.Count == 2) { nextCellIsHeader = cells[1].GetIsGroupHeader <ItemsView <Cell>, Cell>(); } } if (cell == null) { cell = GetCellForPosition(position); if (cell == null) { return(new AView(_context)); } } } var cellIsBeingReused = false; var layout = convertView as ConditionalFocusLayout; if (layout != null) { cellIsBeingReused = true; convertView = layout.GetChildAt(0); } else { layout = new ConditionalFocusLayout(_context) { Orientation = Orientation.Vertical }; _layoutsCreated.Add(layout); } if (((cachingStrategy & ListViewCachingStrategy.RecycleElement) != 0) && convertView != null) { var boxedCell = convertView as INativeElementView; if (boxedCell == null) { throw new InvalidOperationException($"View for cell must implement {nameof(INativeElementView)} to enable recycling."); } cell = (Cell)boxedCell.Element; #pragma warning disable CS0618 // Type or member is obsolete // The Platform property is no longer necessary, but we have to set it because some third-party // library might still be retrieving it and using it cell.Platform = _listView.Platform; #pragma warning restore CS0618 // Type or member is obsolete ICellController cellController = cell; cellController.SendDisappearing(); int row = position; var group = 0; var templatedItems = TemplatedItemsView.TemplatedItems; if (_listView.IsGroupingEnabled) { group = templatedItems.GetGroupIndexFromGlobal(position, out row); } var templatedList = templatedItems.GetGroup(group); if (_listView.IsGroupingEnabled) { if (row == 0) { templatedList.UpdateHeader(cell, group); } else { templatedList.UpdateContent(cell, row - 1); } } else { templatedList.UpdateContent(cell, row); } cellController.SendAppearing(); if (cell.BindingContext == ActionModeObject) { ActionModeContext = cell; ContextView = layout; } if (ReferenceEquals(_listView.SelectedItem, cell.BindingContext)) { Select(_listView.IsGroupingEnabled ? row - 1 : row, layout); } else if (cell.BindingContext == ActionModeObject) { SetSelectedBackground(layout, true); } else { UnsetSelectedBackground(layout); } Performance.Stop(reference); return(layout); } AView view = CellFactory.GetCell(cell, convertView, parent, _context, _listView); Performance.Start(reference, "AddView"); if (cellIsBeingReused) { if (convertView != view) { layout.RemoveViewAt(0); layout.AddView(view, 0); } } else { layout.AddView(view, 0); } Performance.Stop(reference, "AddView"); bool isHeader = cell.GetIsGroupHeader <ItemsView <Cell>, Cell>(); AView bline; UpdateSeparatorVisibility(cell, cellIsBeingReused, isHeader, nextCellIsHeader, layout, out bline); UpdateSeparatorColor(isHeader, bline); if ((bool)cell.GetValue(IsSelectedProperty)) { Select(position, layout); } else { UnsetSelectedBackground(layout); } layout.ApplyTouchListenersToSpecialCells(cell); Performance.Stop(reference); return(layout); }
public override AView GetView(int position, AView convertView, ViewGroup parent) { Cell cell = null; Performance.Start(); ListViewCachingStrategy cachingStrategy = _listView.CachingStrategy; var nextCellIsHeader = false; if (cachingStrategy == ListViewCachingStrategy.RetainElement || convertView == null) { if (_listView.IsGroupingEnabled) { List <Cell> cells = GetCellsFromPosition(position, 2); if (cells.Count > 0) { cell = cells[0]; } if (cells.Count == 2) { nextCellIsHeader = TemplatedItemsList <ItemsView <Cell>, Cell> .GetIsGroupHeader(cells[1]); } } if (cell == null) { cell = GetCellForPosition(position); if (cell == null) { return(new AView(_context)); } } } var makeBline = true; var layout = convertView as ConditionalFocusLayout; if (layout != null) { makeBline = false; convertView = layout.GetChildAt(0); } else { layout = new ConditionalFocusLayout(_context) { Orientation = Orientation.Vertical } }; if (cachingStrategy == ListViewCachingStrategy.RecycleElement && convertView != null) { var boxedCell = (INativeElementView)convertView; if (boxedCell == null) { throw new InvalidOperationException($"View for cell must implement {nameof(INativeElementView)} to enable recycling."); } cell = (Cell)boxedCell.Element; if (ActionModeContext == cell) { // This appears to never happen, the theory is android keeps all views alive that are currently selected for long-press (preventing them from being recycled). // This is convenient since we wont have to worry about the user scrolling the cell offscreen and us losing our context actions. ActionModeContext = null; ContextView = null; } // We are going to re-set the Platform here because in some cases (headers mostly) its possible this is unset and // when the binding context gets updated the measure passes will all fail. By applying this hear the Update call // further down will result in correct layouts. cell.Platform = _listView.Platform; cell.SendDisappearing(); int row = position; var group = 0; if (_listView.IsGroupingEnabled) { group = _listView.TemplatedItems.GetGroupIndexFromGlobal(position, out row); } TemplatedItemsList <ItemsView <Cell>, Cell> templatedList = _listView.TemplatedItems.GetGroup(group); if (_listView.IsGroupingEnabled) { if (row == 0) { templatedList.UpdateHeader(cell, group); } else { templatedList.UpdateContent(cell, row - 1); } } else { templatedList.UpdateContent(cell, row); } cell.SendAppearing(); if (cell.BindingContext == ActionModeObject) { ActionModeContext = cell; ContextView = layout; } if (ReferenceEquals(_listView.SelectedItem, cell.BindingContext)) { Select(_listView.IsGroupingEnabled ? row - 1 : row, layout); } else if (cell.BindingContext == ActionModeObject) { SetSelectedBackground(layout, true); } else { UnsetSelectedBackground(layout); } Performance.Stop(); return(layout); } AView view = CellFactory.GetCell(cell, convertView, parent, _context, _listView); Performance.Start("AddView"); if (!makeBline) { if (convertView != view) { layout.RemoveViewAt(0); layout.AddView(view, 0); } } else { layout.AddView(view, 0); } Performance.Stop("AddView"); AView bline; if (makeBline) { bline = new AView(_context) { LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, 1) }; layout.AddView(bline); } else { bline = layout.GetChildAt(1); } bool isHeader = TemplatedItemsList <ItemsView <Cell>, Cell> .GetIsGroupHeader(cell); Color separatorColor = _listView.SeparatorColor; if (nextCellIsHeader || _listView.SeparatorVisibility == SeparatorVisibility.None) { bline.SetBackgroundColor(global::Android.Graphics.Color.Transparent); } else if (isHeader || !separatorColor.IsDefault) { bline.SetBackgroundColor(separatorColor.ToAndroid(Color.Accent)); } else { if (s_dividerHorizontalDarkId == int.MinValue) { using (var value = new TypedValue()) { int id = global::Android.Resource.Drawable.DividerHorizontalDark; if (_context.Theme.ResolveAttribute(global::Android.Resource.Attribute.ListDivider, value, true)) { id = value.ResourceId; } else if (_context.Theme.ResolveAttribute(global::Android.Resource.Attribute.Divider, value, true)) { id = value.ResourceId; } s_dividerHorizontalDarkId = id; } } bline.SetBackgroundResource(s_dividerHorizontalDarkId); } if ((bool)cell.GetValue(IsSelectedProperty)) { Select(position, layout); } else { UnsetSelectedBackground(layout); } layout.ApplyTouchListenersToSpecialCells(cell); Performance.Stop(); return(layout); }
public override AView GetView(int position, AView convertView, ViewGroup parent) { bool isHeader, nextIsHeader; Cell item = GetCellForPosition(position, out isHeader, out nextIsHeader); if (item == null) { return(new AView(Context)); } var makeBline = true; var layout = convertView as ConditionalFocusLayout; if (layout != null) { makeBline = false; convertView = layout.GetChildAt(0); } else { layout = new ConditionalFocusLayout(Context) { Orientation = Orientation.Vertical } }; AView aview = CellFactory.GetCell(item, convertView, parent, Context, _view); if (!makeBline) { if (convertView != aview) { layout.RemoveViewAt(0); layout.AddView(aview, 0); } } else { layout.AddView(aview, 0); } AView bline; if (makeBline) { bline = new AView(Context) { LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, 1) }; layout.AddView(bline); } else { bline = layout.GetChildAt(1); } if (isHeader) { bline.SetBackgroundColor(Color.Accent.ToAndroid()); } else if (nextIsHeader) { bline.SetBackgroundColor(global::Android.Graphics.Color.Transparent); } else { using (var value = new TypedValue()) { int id = global::Android.Resource.Drawable.DividerHorizontalDark; if (Context.Theme.ResolveAttribute(global::Android.Resource.Attribute.ListDivider, value, true)) { id = value.ResourceId; } else if (Context.Theme.ResolveAttribute(global::Android.Resource.Attribute.Divider, value, true)) { id = value.ResourceId; } bline.SetBackgroundResource(id); } } layout.ApplyTouchListenersToSpecialCells(item); if (_restoreFocus == item) { if (!aview.HasFocus) { aview.RequestFocus(); } _restoreFocus = null; } else if (aview.HasFocus) { aview.ClearFocus(); } return(layout); }