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);
            }
        }
Beispiel #2
0
        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();

            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);
        }
Beispiel #4
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);
        }
		void UpdateSeparatorVisibility(Cell cell, bool cellIsBeingReused, bool isHeader, bool nextCellIsHeader, ConditionalFocusLayout layout, out AView bline)
		{
			bline = null;
			if (cellIsBeingReused)
				return;
			var makeBline = _listView.SeparatorVisibility == SeparatorVisibility.Default || isHeader && !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);
			}
		}