public override int ScrollVerticallyBy(int dy, Recycler recycler, State state) { var delta = new IntVector(0, dy); ScrollBy(ref delta, recycler, state); return(delta.Y); }
public override int ScrollHorizontallyBy(int dx, Recycler recycler, State state) { var delta = new IntVector(dx, 0); ScrollBy(ref delta, recycler, state); return(delta.X); }
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); } }
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); }
public override void SmoothScrollToPosition(Android.Support.V7.Widget.RecyclerView recyclerView, Android.Support.V7.Widget.RecyclerView.State state, int position) { CustomLinearSmoothScroller linearSmoothScroller = new CustomLinearSmoothScroller(recyclerView.Context); linearSmoothScroller.SetManager(this); linearSmoothScroller.TargetPosition = position; StartSmoothScroll(linearSmoothScroller); }
public override void GetItemOffsets(Rect outRect, View view, RecyclerView parent, Android.Support.V7.Widget.RecyclerView.State state) { outRect.Left = space; outRect.Right = space; outRect.Bottom = space; if (parent.GetChildAdapterPosition(view) == 0) { outRect.Top = space; } }
internal abstract IntRectangle GetBounds(int positionOrigin, State state);
internal override IntRectangle GetBounds(int originPosition, State state) => new IntRectangle( LayoutItem(originPosition, 0).Location, new IntSize(_itemSize.Width * state.ItemCount, _itemSize.Height) );
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); } }
public override void SmoothScrollToPosition(RecyclerView recyclerView, State state, int adapterPosition) { ScrollToPosition(adapterPosition); }