Exemple #1
0
        public override int ScrollVerticallyBy(int dy, Recycler recycler, State state)
        {
            var delta = new IntVector(0, dy);

            ScrollBy(ref delta, recycler, state);
            return(delta.Y);
        }
Exemple #2
0
        public override int ScrollHorizontallyBy(int dx, Recycler recycler, State state)
        {
            var delta = new IntVector(dx, 0);

            ScrollBy(ref delta, recycler, state);
            return(delta.X);
        }
Exemple #3
0
 public override void OnLayoutChildren(Android.Support.V7.Widget.RecyclerView.Recycler recycler,
                                       Android.Support.V7.Widget.RecyclerView.State state)
 {
     try
     {
         base.OnLayoutChildren(recycler, state);
     }
     catch (IndexOutOfBoundsException e)
     {
         Mvx.Warning(
             "Workaround of issue - https://code.google.com/p/android/issues/detail?id=77846#c1 - IndexOutOfBoundsException " +
             e.Message);
     }
 }
Exemple #4
0
        void ScrollBy(ref IntVector delta, Recycler recycler, State state)
        {
            _adapterChangeType = default(AdapterChangeType);

            delta = Viewport.BoundTranslation(
                delta: delta,
                bound: _virtualLayout.GetBounds(_positionOrigin, state)
                );

            _locationOffset += delta;
            _samples.Insert(0, delta);
            _samples.RemoveAt(_samples.Count - 1);

            OffsetChildren(delta);
            OnLayoutChildren(recycler, state);
        }
Exemple #5
0
 internal void DetachAndScrap(Recycler recycler)
 {
     _layout.DetachAndScrapView(_view, recycler);
 }
Exemple #6
0
        public override void OnLayoutChildren(Recycler recycler, State state)
        {
            var adapterChangeType = _adapterChangeType;

            if (state.IsPreLayout)
            {
                adapterChangeType = default(AdapterChangeType);
            }

            // adapter updates
            if (!state.IsPreLayout)
            {
                while (_deferredLayout.Count > 0)
                {
                    _deferredLayout.Dequeue()(recycler, state);
                }
            }

            // get visible items
            var positions = _virtualLayout.GetPositions(
                positionOrigin: _positionOrigin,
                itemCount: state.ItemCount,
                viewport: Viewport
                ).ToRange();

            // disappearing
            var disappearing = _viewByAdaptorPosition.Keys.Except(positions).ToList();

            // defer cleanup of displaced items and lay them out off-screen so they animate off-screen
            if (adapterChangeType == AdapterChangeType.Added)
            {
                positions = positions.Concat(disappearing).OrderBy(o => o).ToArray();
                disappearing.Clear();
            }

            // recycle
            foreach (var position in disappearing)
            {
                var view = _viewByAdaptorPosition[position];

                // remove
                _viewByAdaptorPosition.Remove(position);

                // scrap
                new DecoratedView(this, view).DetachAndScrap(recycler);
            }

            // TODO: Generalize
            if (adapterChangeType == AdapterChangeType.Removed && _positionOrigin == state.ItemCount - 1)
            {
                var vlayout = _virtualLayout.LayoutItem(_positionOrigin, _positionOrigin);
                _locationOffset = new IntVector(vlayout.Width - Width, _locationOffset.Y);
            }

            _visibleAdapterPosition.Clear();
            var nextLocationOffset = new IntPoint(int.MaxValue, int.MaxValue);
            var nextPositionOrigin = int.MaxValue;

            foreach (var position in positions)
            {
                // attach
                AndroidView view;
                if (!_viewByAdaptorPosition.TryGetValue(position, out view))
                {
                    AddView(_viewByAdaptorPosition[position] = view = recycler.GetViewForPosition(position));
                }

                // layout
                var decoratedView  = new DecoratedView(this, view);
                var layout         = _virtualLayout.LayoutItem(_positionOrigin, position);
                var physicalLayout = layout - _locationOffset;
                decoratedView.Layout(physicalLayout);

                var isVisible = Viewport.IntersectsWith(layout);
                if (isVisible)
                {
                    _visibleAdapterPosition.Add(position);
                }

                // update offsets
                if (isVisible && position < nextPositionOrigin)
                {
                    nextLocationOffset = layout.Location;
                    nextPositionOrigin = position;
                }
            }

            // update origin
            if (nextPositionOrigin != int.MaxValue)
            {
                _positionOrigin  = nextPositionOrigin;
                _locationOffset -= (IntVector)nextLocationOffset;
            }

            // scrapped views not re-attached must be recycled (why isn't this done by Android, I dunno)
            foreach (var viewHolder in recycler.ScrapList.ToArray())
            {
                recycler.RecycleView(viewHolder.ItemView);
            }
        }