Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 91519

Accordion List View

$
0
0

Hi,

I've been working on a custom renderer to create an Accordion controller. So far I was successful using Xamarin Labs - EditableListView as reference.

Here's how the code is so far for the custom renderer: AccordionListViewRenderer

`
public UITableView _tableView;
private AccordionTableViewSource _editableListViewSource;
public readonly float _rowListHeight = 100;
public readonly float _rowSelectedHeight = 600;
public static int _selectedRow = -1;
public static int _oldSelectedRow = -1;

    protected override void OnElementChanged(ElementChangedEventArgs<AccordionListView<T>> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement == null)
        {
            _tableView = new UITableView(new RectangleF(0, 0, 1, 1), UITableViewStyle.Plain);
            SetNativeControl(_tableView);
        }

        Unbind(e.OldElement);
        Bind(e.NewElement);

        _editableListViewSource = new AccordionTableViewSource(this);
        _tableView.Source = _editableListViewSource;
        _tableView.BackgroundView = new UIView();
        _tableView.TableFooterView = new UIView();
    }

    private void Unbind(AccordionListView<T> oldElement)
    {
        if (oldElement != null)
        {
            oldElement.PropertyChanged -= ElementPropertyChanged;
            oldElement.Source.CollectionChanged += DataCollectionChanged;
        }
    }

    private void Bind(AccordionListView<T> newElement)
    {
        if (newElement != null)
        {
            newElement.PropertyChanged += ElementPropertyChanged;
            newElement.Source.CollectionChanged += DataCollectionChanged;
        }
    }

    private void DataCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        _tableView.ReloadData();
    }

    private void ElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Source")
        {
            Element.Source.CollectionChanged += DataCollectionChanged;
        }
    }

    private class AccordionTableViewSource : UITableViewSource
    {
        AccordionListViewRenderer<T> _containerRenderer;

        public AccordionTableViewSource(AccordionListViewRenderer<T> containerRenderer)
        {
            _containerRenderer = containerRenderer;
        }

        public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
        {

            var item = _containerRenderer.Element.Source[indexPath.Row];
            ViewCell viewCell = Activator.CreateInstance(_containerRenderer.Element.ListViewType) as ViewCell;
            viewCell.BindingContext = item;
            //Create a selected view cell if we are in the selected row.
            if (indexPath.Row == _selectedRow)
            {
                SelectedAdvisorListCell mainCell = Activator.CreateInstance(_containerRenderer.Element.FocusViewType, 
                                _containerRenderer.AccordionListView.Source[_selectedRow],
                                false) as SelectedAdvisorListCell;
                mainCell.BindingContext = item;
                if (_containerRenderer.Element.AdvisorSelectedCallback != null)
                {
                    mainCell.mainAdvisor.chooseButton.Clicked += (sender, e) =>
                    {
                        var advisor = _containerRenderer.AccordionListView.Source[_selectedRow];
                        _containerRenderer.Element.AdvisorSelectedCallback(advisor);
                    };
                }
                mainCell.Height = _containerRenderer._rowSelectedHeight;
                viewCell = (ViewCell)mainCell;
            }
            UITableViewCell cell = new ViewCellRenderer().GetCell(viewCell, tableView);
            return cell;
        }

        public override int RowsInSection(UITableView tableView, int section)
        {
            return _containerRenderer.Element.Source.Count;
        }

        public override float GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
        {
            if (tableView.IndexPathForSelectedRow != null)
            {
                if (tableView.IndexPathForSelectedRow.Row == indexPath.Row && _selectedRow != -1)
                    return _containerRenderer._rowSelectedHeight;
            }
            return _containerRenderer._rowListHeight;
        }

        public override void RowSelected(UITableView tableView, NSIndexPath indexPath)
        {

            _selectedRow = indexPath.Row;
            NSIndexPath[] rowsToReload;
            if (_oldSelectedRow >= 0)
            {
                //If we have the selected row the same as the old one, resize to hide/show the details.
                if (_selectedRow == _oldSelectedRow)
                {
                    rowsToReload = new NSIndexPath[] {
                        NSIndexPath.FromRowSection(indexPath.Row, 0)
                    };
                }
                else //refresh both the clicked and the last clicked cells
                {
                    rowsToReload = new NSIndexPath[] {
                        NSIndexPath.FromRowSection(_oldSelectedRow, 0),
                        NSIndexPath.FromRowSection(indexPath.Row, 0)
                    };
                }
            }
            else
            {
                rowsToReload = new NSIndexPath[] {
                    NSIndexPath.FromRowSection(indexPath.Row, 0)
                };
            }

            tableView.ReloadRows(rowsToReload, UITableViewRowAnimation.Top);
            _oldSelectedRow = indexPath.Row;
        }
    }
}`

On the GetCell I'm creating new instances of Xamarin classes that extend from ViewCell and hold a stacklayout.

Right now I'm facing two problems:

  • All of the subviews inside my type classes (used to create on the GetCell) have a -1 Width and -1 Height. This won't change unless I manually set a WidthRequest and HeightRequest for all children.
  • After iOS update, when I select another row, it doesn't expand anymore. The content height was going all the way to 600, now it's going just a little bit further than 100 and it stop there.

Maybe I got this thing all wrong, any idea?

Thank you!


Viewing all articles
Browse latest Browse all 91519

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>