-
-
Save rocel/95131311bd367d090ab6 to your computer and use it in GitHub Desktop.
This file contains 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 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