public bool RequestFocus(global::Android.Views.View control, Func <bool> baseRequestFocus) { IViewParent ancestor = control.Parent; var previousFocusability = DescendantFocusability.BlockDescendants; ConditionalFocusLayout cfl = null; // Work our way up through the tree until we find a ConditionalFocusLayout while (ancestor is ViewGroup) { cfl = ancestor as ConditionalFocusLayout; if (cfl != null) { previousFocusability = cfl.DescendantFocusability; // Toggle DescendantFocusability to allow this control to get focus cfl.DescendantFocusability = DescendantFocusability.AfterDescendants; break; } ancestor = ancestor.Parent; } // Call the original RequestFocus implementation for the View bool result = baseRequestFocus(); if (cfl != null) { // Toggle descendantfocusability back to whatever it was cfl.DescendantFocusability = previousFocusability; } return(result); }
void DisposeOfConditionalFocusLayout(ConditionalFocusLayout layout) { var renderedView = layout?.GetChildAt(0); var element = (renderedView as INativeElementView)?.Element; var view = (element as ViewCell)?.View; if (view != null) { var renderer = AppCompat.Platform.GetRenderer(view); if (renderer == renderedView) { element.ClearValue(AppCompat.Platform.RendererProperty); } renderer?.Dispose(); renderer = null; } renderedView?.Dispose(); renderedView = null; }
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); }
void UpdateSeparatorVisibility(Cell cell, bool cellIsBeingReused, bool isHeader, bool nextCellIsHeader, bool isSeparatorVisible, ConditionalFocusLayout layout, out AView bline) { bline = null; if (cellIsBeingReused && layout.ChildCount > 1) { layout.RemoveViewAt(1); } var makeBline = isSeparatorVisible || isHeader && isSeparatorVisible && !nextCellIsHeader; if (makeBline) { bline = new AView(_context) { LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, 1) }; layout.AddView(bline); } else if (layout.ChildCount > 1) { layout.RemoveViewAt(1); } }
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) { Performance.Stop(reference); 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; 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; bool isSeparatorVisible = _listView.SeparatorVisibility == SeparatorVisibility.Default; if (isSeparatorVisible) { UpdateSeparatorVisibility(cell, cellIsBeingReused, isHeader, nextCellIsHeader, isSeparatorVisible, layout, out bline); UpdateSeparatorColor(isHeader, bline); } else if (layout.ChildCount > 1) { layout.RemoveViewAt(1); } if ((bool)cell.GetValue(IsSelectedProperty)) { Select(position, layout); } else { UnsetSelectedBackground(layout); } layout.ApplyTouchListenersToSpecialCells(cell); Performance.Stop(reference); return(layout); }