Last active

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Mixed grid/list layout built with the new TwoWayView API

View GridAndListLayout.java
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
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();
}
}

Hi Lucas,

Seems that the getLayoutEnd() and getLayoutStart() methods do not exist in current version of TwoWayLayoutManager.Thus, I need to implement them locally. I'm a bit newbee with RecyclerView, would it be possible for you to help on this?

Many Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.