Skip to content

Instantly share code, notes, and snippets.

@rafaelkowal
Forked from lucasr/GridAndListLayout.java
Created July 30, 2014 14:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rafaelkowal/6c2edc711e6e5bad2444 to your computer and use it in GitHub Desktop.
Save rafaelkowal/6c2edc711e6e5bad2444 to your computer and use it in GitHub Desktop.
public class GridAndListLayout extends TWAbsLayoutManager {
private final int NUM_LANES = 2;
public GridAndListLayout(Context context, Orientation orientation) {
super(context, orientation);
}
private boolean isVertical() {
return (getOrientation() == Orientation.VERTICAL);
}
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 (isVertical()) {
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 (isVertical()) {
offset = getDecoratedMeasuredHeight(lastChild);
} else {
offset = getDecoratedMeasuredWidth(lastChild);
}
} else {
offset = 0;
}
return getLayoutEnd() - offset;
}
/* This method will become optional soon. */
@Override
protected int getLayoutStart() {
final View child = getChildAt(0);
if (child != null) {
return (isVertical() ? getDecoratedTop(child) : getDecoratedLeft(child));
}
return 0;
}
/* This method will become optional soon. */
@Override
protected int getLayoutEnd() {
final View child = getChildAt(getChildCount() - 1);
if (child != null) {
return (isVertical() ? getDecoratedBottom(child) : getDecoratedRight(child));
}
return 0;
}
@Override
protected void measureChild(View child) {
int widthUsed = 0;
int heightUsed = 0;
if (isGridItem(getPosition(child))) {
if (isVertical()) {
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 = isVertical();
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 void detachChild(View child, Direction direction) {
// No need to do anything.
}
@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