Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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;
        }
Esempio n. 3
0
        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);
            }
        }
Esempio n. 4
0
        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;

#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;

            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);
        }
Esempio n. 5
0
        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);
        }