Get the basics right before getting started:
1, inheritance RecyclerView. LayoutManager
public class LinearLayoutManager extends RecyclerView.LayoutManager implements
ItemTouchHelper.ViewDropHandler, RecyclerView.SmoothScroller.ScrollVectorProvider {
}
Copy the code
2, implementation generateDefaultLayoutParams
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
Copy the code
3. Rewrite the isAutoMeasureEnabled or onMeasure method
@Override public boolean isAutoMeasureEnabled() { return true; } // The isAutoMeasureEnabled and onMeasure methods are mutually exclusive. Override one of them as required. // Three layOutManagers of RecyclerView all implement isAutoMeasureEnabled @override public void onMeasure(@NonNull RecyclerView.Recycler recycler, @NonNull RecyclerView.State state, int widthSpec, int heightSpec) { super.onMeasure(recycler, state, widthSpec, heightSpec); }Copy the code
4. Overwrite onLayoutChildren and start filling child Views.
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
super.onLayoutChildren(recycler, state);
}
Copy the code
This example overrides canScrollVerticall or canScrollHorizontally to determine the sliding direction.
@Override
public boolean canScrollVertically() {
return true;
}
Copy the code
Rewrite scrollVerticallyBy or scrollHorizontallyBy to do boundary processing, item recycling and reuse logic while sliding
@Override public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, Int realDy = dy; int realDy = dy; int realDy = dy; . return realDy ; }Copy the code
7, scrollToPosition() and smoothScrollToPosition() method support
Directly see LinearLayoutManager. ScrollToPosition code:
@Override public void scrollToPosition(int position) { mPendingScrollPosition = position; mPendingScrollPositionOffset = INVALID_OFFSET; if (mPendingSavedState ! = null) { mPendingSavedState.invalidateAnchor(); } requestLayout(); }Copy the code
7.1. Set mPendingScrollPosition to the position to scroll to and call requestLayout (), which calls onLayoutChildren. Will call in the onLayoutChildren updateAnchorFromPendingData () according to the position for the view to see if the view is in the midst of the screen, and then according to the position to judge the view from left to right layout, or from right to left layout
private boolean updateAnchorFromPendingData(RecyclerView.State state, AnchorInfo anchorInfo) { ... If (mPendingScrollPositionOffset = = INVALID_OFFSET) {/ / according to the position for need to scroll to view the view child = findViewByPosition(mPendingScrollPosition); // If the view is in the screen (it may not be fully displayed) = null) { ... / / access to view the left edge of the final int startGap = mOrientationHelper. GetDecoratedStart (child) mOrientationHelper.getStartAfterPadding(); / / if less than 0 not fully display The left edge in screen outside the if (startGap < 0) {anchorInfo. MCoordinate = mOrientationHelper. GetStartAfterPadding (); / / layout anchorInfo from left to right. MLayoutFromEnd = false; return true; } / / use the width of the layoutManager minus the right edge of the view final int endGap = mOrientationHelper. GetEndAfterPadding () mOrientationHelper.getDecoratedEnd(child); / / if the result is less than 0 indicates right edge in the screen outside the if (endGap < 0) {anchorInfo. MCoordinate = mOrientationHelper. GetEndAfterPadding (); / / layout anchorInfo from right to left. MLayoutFromEnd = true; return true; }... If (getChildCount() > 0) {if (getChildCount() > 0) {// Get position of any child, Int pos = getPosition(getChildAt(0)); / / by comparing the current need to scroll to view the position and the current display of the view of the position to determine how to layout anchorInfo. MLayoutFromEnd = mPendingScrollPosition < pos = = mShouldReverseLayout; }... } return true;Copy the code
8, smoothScrollToPosition()
//LinearLayuotManager
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
int position) {
LinearSmoothScroller linearSmoothScroller =
new LinearSmoothScroller(recyclerView.getContext());
linearSmoothScroller.setTargetPosition(position);
startSmoothScroll(linearSmoothScroller);
}
Copy the code
8.1 Customized layoutManager implements the ScrollVectorProvider interface
public class LinearLayoutManager extends RecyclerView.LayoutManager implements
ItemTouchHelper.ViewDropHandler, RecyclerView.SmoothScroller.ScrollVectorProvider {
}
Copy the code
8.2 rewrite computeScrollVectorForPosition method
@Override public PointF computeScrollVectorForPosition(int targetPosition) { if (getChildCount() == 0) { return null; } final int firstChildPos = getPosition(getChildAt(0)); final int direction = targetPosition < firstChildPos ! = mShouldReverseLayout ? 1:1; if (mOrientation == HORIZONTAL) { return new PointF(direction, 0); } else { return new PointF(0, direction); }}Copy the code
9. Recycle View: If you can accurately recycle and reuse Holder during the first layout and sliding, you can directly get Holder in mAttachedScrap and put it directly into mRecyclerPool for recycling. Every time (such as sliding detachAndScrapAttachedViews have call, then go in the cache to useful itemview)
List scrapList = recycler.getscraplist (); RemoveAndRecycleView for (int I = 0; i < scrapList.size(); i++) { RecyclerView.ViewHolder holder = scrapList.get(i); removeView(holder.itemView); recycler.recycleView(holder.itemView); }Copy the code
Otherwise, you need to calculate the start and end index to recycle
private void recycleChildren(RecyclerView.Recycler recycler, int startIndex, int endIndex) { if (startIndex == endIndex) { return; } if (endIndex > startIndex) { for (int i = endIndex - 1; i >= startIndex; i--) { removeAndRecycleViewAt(i, recycler); } } else { for (int i = startIndex; i > endIndex; i--) { removeAndRecycleViewAt(i, recycler); }}}Copy the code
The above steps are required to customize Layoutmananger. Note that the above is not a complete code. In fact, the business logic is still supplemented in each step