Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Mastering RecyclerView Layouts

31,262 views

Published on

An overview of the process for building your own RecyclerView LayoutManager

Published in: Technology

Mastering RecyclerView Layouts

  1. 1. Mastering RecyclerView Layouts Dave Smith • NewCircle, Inc. @devunwired +DaveSmithDev
  2. 2. Why Am I Here? Help Reduce Sanitarium Admissions caused by RecyclerView Layouts.
  3. 3. RecyclerView recyclerView = new RecyclerView(this);
 recyclerView.setLayoutManager(…);
 
 setContentView(recyclerView);
  4. 4. LinearLayoutManager LinearLayoutManager manager = new LinearLayoutManager(
 this,
 LinearLayoutManager.VERTICAL,
 false);
  5. 5. GridLayoutManager GridLayoutManager manager = new GridLayoutManager( this,
 2, /* Number of grid columns */
 GridLayoutManager.VERTICAL,
 false);
  6. 6. GridLayoutManager GridLayoutManager manager = new GridLayoutManager( this,
 2, /* Number of grid columns */
 GridLayoutManager.VERTICAL,
 false); manager.setSpanSizeLookup(
 new GridLayoutManager.SpanSizeLookup() {
 @Override
 public int getSpanSize(int position) {
 //Stagger every other row
 return (position % 3 == 0 ? 2 : 1);
 }
 });
  7. 7. StaggeredGridLayoutManager StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(
 2, /* Number of grid columns */
 StaggeredGridLayoutManager.VERTICAL);
  8. 8. Case Study: FixedGridLayoutManager 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
  9. 9. The Recycler LayoutManager Recycler Adapter Obtain View Recycle View Bind
  10. 10. The Recycler LayoutManager Recycler Adapter Obtain View Recycle View Bind
  11. 11. The Recycler Scrap Heap detachAndScrapView() Recycle Pool removeAndRecycleView()
  12. 12. Handling Decorations Item View getDecoratedLeft() getDecoratedTop() getDecoratedRight() getDecoratedBottom()
  13. 13. Handling Decorations Item View getDecoratedWidth() getDecoratedHeight()
  14. 14. Handling Decorations Item View layoutDecorated() measureChild()
  15. 15. The Fill Technique fillGaps() Discover first visible position/location Find layout gaps (at the edges) Scrap everything Lay out all visible positions Save as little state as possible. Is there space before the first visible position? Is there space after the last visible position?
  16. 16. The Fill Technique private void fillGrid(int direction, …,
 RecyclerView.Recycler recycler,
 RecyclerView.State state) {
 //…Obtain the first visible item position… 
 detachAndScrapAttachedViews(recycler);
 
 for (…) {
 int nextPosition = …;
 
 View View = recycler.getViewForPosition(nextPosition); addView(view);
 
 measureChildWithMargins(view, …);
 layoutDecorated(view, …);
 }
 

  17. 17. private void fillGrid(int direction, …,
 RecyclerView.Recycler recycler,
 RecyclerView.State state) {
 //…Obtain the first visible item position… 
 detachAndScrapAttachedViews(recycler);
 
 for (…) {
 int nextPosition = …;
 
 View View = recycler.getViewForPosition(nextPosition); addView(view);
 
 measureChildWithMargins(view, …);
 layoutDecorated(view, …);
 }
 
 //Remove anything that is left behind final List<RecyclerView.ViewHolder> scrapList = recycler.getScrapList();
 for (int i=0; i < scrapList.size(); i++) {
 final View removingView = scrapList.get(i);
 recycler.recycleView(removingView);
 }
 }
  18. 18. 0 1 2 3 4 5 6 7 Use Attach/ Detach to quickly reorder view indices.
  19. 19. Level 1: Make It Work onLayoutChildren() Run a FILL operation canScrollVertically() canScrollHorizontally() Which axes enable scrolling? scrollHorizontallyBy() scrollVerticallyBy() Clamp supplied delta against boundary conditions Shift all views in the layout Trigger a FILL operation Report back actual distance scrolled
  20. 20. Level 1: Make It Work public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
 …
 
 int delta;
 if (dx > 0) { // Contents are scrolling left
 delta = …;
 } else { // Contents are scrolling right
 delta = …;
 }
 
 offsetChildrenHorizontal(delta);
 
 if (dx > 0) {
 fillGrid(DIRECTION_START, …, recycler, state);
 } else {
 fillGrid(DIRECTION_END, …, recycler, state);
 }
 
 return -delta;
 }
  21. 21. Level 2: Data Set Changes onAdapterChanged() removeAllViews() notifyDataSetChanged() -> onLayoutChanged() Treat as a new layout, and just run a FILL…
  22. 22. Level 3: Add Some Flair scrollToPosition() Track Requested Position Trigger requestLayout() smoothScrollToPosition() Create a SmoothScroller instance Set the target position Invoke startSmoothScroll()
  23. 23. Level 3: Add Some Flair LinearSmoothScroller scroller = new LinearSmoothScroller(recyclerView.getContext()) {
 
 @Override
 public PointF computeScrollVectorForPosition(int targetPosition) {
 final int rowOffset = …;
 final int columnOffset = …;
 
 return new PointF(columnOffset * stepWidth, rowOffset * stepHeight);
 }
 }; 
 scroller.setTargetPosition(position);
 startSmoothScroll(scroller);
  24. 24. Level 4: Zen Master supportsPredictiveItemAnimations() We have more to say about animations… onLayoutChildren() [isPreLayout() == true] Note any removed views -> LayoutParams.isViewRemoved() Add extra views during FILL to cover space left behind onLayoutChildren() Place disappearing views off-screen
  25. 25. public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
 … 
 if (state.isPreLayout()) {
 final View child = getChildAt(…); final LayoutParams lp = (LayoutParams) child.getLayoutParams();
 if (lp.isItemRemoved()) { //Track and count view removals… }
 }
 
 //Clear all attached views into the recycle bin
 detachAndScrapAttachedViews(recycler);
 
 //Fill the grid for the initial layout of views
 fillGrid(…);
 
 //Anything left? Lay out for disappearing animation
 if (!state.isPreLayout() && !recycler.getScrapList().isEmpty()) {
 final List<RecyclerView.ViewHolder> scrapList = recycler.getScrapList();
 //Laying out a scrap item removes it from the list… //Beware concurrent modification! 
 …
 }
 }
  26. 26. Default Item Animations
  27. 27. Predictive Item Animations
  28. 28. Resources RecyclerView Playground https://github.com/devunwired/recyclerview-playground Building a RecyclerView LayoutManager http://wiresareobsolete.com/ Redux - Handling Disconnected Ranges Android SDK Reference https://developer.android.com/training/material/lists-cards.html

×