Last active
March 29, 2017 15:35
-
-
Save lucasr/8ea1832239dcc5119e77 to your computer and use it in GitHub Desktop.
Mixed grid/list layout built with the new TwoWayView API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class GridAndListLayout extends TwoWayLayoutManager { | |
private final int NUM_LANES = 2; | |
public GridAndListLayout(Context context, Orientation orientation) { | |
super(context, orientation); | |
} | |
private boolean isGridItem(int position) { | |
return position < 4; | |
} | |
private int getLaneForPosition(int position) { | |
if (isGridItem(position)) { | |
return position % NUM_LANES; | |
} | |
return 0; | |
} | |
private int getLayoutInnerStart() { | |
final View firstChild = getChildAt(0); | |
final int firstPosition = getPosition(firstChild); | |
final int offset; | |
if (getLaneForPosition(firstPosition) > 0) { | |
if (getOrientation() == Orientation.VERTICAL) { | |
offset = getDecoratedMeasuredHeight(firstChild); | |
} else { | |
offset = getDecoratedMeasuredWidth(firstChild); | |
} | |
} else { | |
offset = 0; | |
} | |
return getLayoutStart() + offset; | |
} | |
private int getLayoutInnerEnd() { | |
final View lastChild = getChildAt(getChildCount() - 1); | |
final int lastPosition = getPosition(lastChild); | |
final int offset; | |
if (isGridItem(lastPosition) && getLaneForPosition(lastPosition) < NUM_LANES - 1) { | |
if (getOrientation() == Orientation.VERTICAL) { | |
offset = getDecoratedMeasuredHeight(lastChild); | |
} else { | |
offset = getDecoratedMeasuredWidth(lastChild); | |
} | |
} else { | |
offset = 0; | |
} | |
return getLayoutEnd() - offset; | |
} | |
@Override | |
protected void measureChild(View child, Direction direction) { | |
int widthUsed = 0; | |
int heightUsed = 0; | |
if (isGridItem(getPosition(child))) { | |
if (getOrientation() == Orientation.VERTICAL) { | |
widthUsed = (getWidth() - getPaddingLeft() - getPaddingRight()) / 2; | |
} else { | |
heightUsed = (getHeight() - getPaddingTop() - getPaddingBottom()) / 2; | |
} | |
} | |
measureChildWithMargins(child, widthUsed, heightUsed); | |
} | |
@Override | |
protected void layoutChild(View child, Direction direction) { | |
final int width = getDecoratedMeasuredWidth(child); | |
final int height = getDecoratedMeasuredHeight(child); | |
final int position = getPosition(child); | |
final int gridLane = getLaneForPosition(position); | |
final boolean isVertical = (getOrientation() == Orientation.VERTICAL); | |
final boolean isGridItem = isGridItem(position); | |
final int gridOffset; | |
if (isGridItem) { | |
gridOffset = (isVertical ? width : height) * gridLane; | |
} else { | |
gridOffset = 0; | |
} | |
int l, t, r, b; | |
if (isVertical) { | |
l = getPaddingLeft() + gridOffset; | |
t = (direction == Direction.END ? getLayoutEnd() : getLayoutStart() - height); | |
} else { | |
l = (direction == Direction.END ? getLayoutEnd() : getLayoutStart() - width); | |
t = getPaddingTop() + gridOffset; | |
} | |
if (isGridItem) { | |
if (direction == Direction.END && gridLane > 0) { | |
if (isVertical) { | |
t -= height; | |
} else { | |
l -= width; | |
} | |
} else if (direction == Direction.START && gridLane < NUM_LANES - 1) { | |
if (isVertical) { | |
t += height; | |
} else { | |
l += width; | |
} | |
} | |
} | |
r = l + width; | |
b = t + height; | |
layoutDecorated(child, l, t, r, b); | |
} | |
@Override | |
protected boolean canAddMoreViews(Direction direction, int limit) { | |
if (direction == Direction.END) { | |
return getLayoutInnerEnd() < getEndWithPadding(); | |
} else { | |
return getLayoutInnerStart() > getStartWithPadding(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have the same issue that @bbouffaut has. please respond as soon as possible