下面列出了android.support.v7.widget.OrientationHelper#getTotalSpace ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private View findEndView(RecyclerView.LayoutManager layoutManager,
OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
int lastChild = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
if (lastChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(lastChild);
float visibleWidth;
if (mIsRtlHorizontal) {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
}
// If we're at the start of the list, we shouldn't snap
// to avoid having the first item not completely visible.
boolean startOfList = ((LinearLayoutManager) layoutManager)
.findFirstCompletelyVisibleItemPosition() == 0;
if (visibleWidth > 0.5f && !startOfList) {
return child;
} else if (mSnapLastItemEnabled && startOfList) {
return child;
} else if (startOfList) {
return null;
} else {
// If the child wasn't returned, we need to return the previous view
return layoutManager.findViewByPosition(lastChild - 1);
}
}
return null;
}
private View findEndView(RecyclerView.LayoutManager layoutManager,
OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
int lastChild = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
if (lastChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(lastChild);
float visibleWidth;
if (isRtlHorizontal) {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
}
// If we're at the start of the list, we shouldn't snap
// to avoid having the first item not completely visible.
boolean startOfList = ((LinearLayoutManager) layoutManager)
.findFirstCompletelyVisibleItemPosition() == 0;
if (visibleWidth > 0.5f && !startOfList) {
return child;
} else if (startOfList) {
return null;
} else {
// If the child wasn't returned, we need to return the previous view
return layoutManager.findViewByPosition(lastChild - 1);
}
}
return null;
}
@Nullable
private View findStartView(RecyclerView.LayoutManager layoutManager,
@NonNull OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
boolean reverseLayout = linearLayoutManager.getReverseLayout();
int firstChild = reverseLayout ? linearLayoutManager.findLastVisibleItemPosition()
: linearLayoutManager.findFirstVisibleItemPosition();
int offset = 1;
if (layoutManager instanceof GridLayoutManager) {
offset += ((GridLayoutManager) layoutManager).getSpanCount() - 1;
}
if (firstChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(firstChild);
float visibleWidth;
if (isRtlHorizontal) {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
}
boolean endOfList;
if (!reverseLayout) {
endOfList = ((LinearLayoutManager) layoutManager)
.findLastCompletelyVisibleItemPosition()
== layoutManager.getItemCount() - 1;
} else {
endOfList = ((LinearLayoutManager) layoutManager)
.findFirstCompletelyVisibleItemPosition()
== 0;
}
if (visibleWidth > 0.5f && !endOfList) {
return child;
} else if (snapLastItem && endOfList) {
return child;
} else if (endOfList) {
return null;
} else {
return reverseLayout ? layoutManager.findViewByPosition(firstChild - offset)
: layoutManager.findViewByPosition(firstChild + offset);
}
}
return null;
}
@Nullable
private View findEndView(RecyclerView.LayoutManager layoutManager,
@NonNull OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
boolean reverseLayout = linearLayoutManager.getReverseLayout();
int lastChild = reverseLayout ? linearLayoutManager.findFirstVisibleItemPosition()
: linearLayoutManager.findLastVisibleItemPosition();
int offset = 1;
if (layoutManager instanceof GridLayoutManager) {
offset += ((GridLayoutManager) layoutManager).getSpanCount() - 1;
}
if (lastChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(lastChild);
float visibleWidth;
if (isRtlHorizontal) {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
}
boolean startOfList;
if (!reverseLayout) {
startOfList = ((LinearLayoutManager) layoutManager)
.findFirstCompletelyVisibleItemPosition() == 0;
} else {
startOfList = ((LinearLayoutManager) layoutManager)
.findLastCompletelyVisibleItemPosition()
== layoutManager.getItemCount() - 1;
}
if (visibleWidth > 0.5f && !startOfList) {
return child;
} else if (snapLastItem && startOfList) {
return child;
} else if (startOfList) {
return null;
} else {
return reverseLayout ? layoutManager.findViewByPosition(lastChild + offset)
: layoutManager.findViewByPosition(lastChild - offset);
}
}
return null;
}
/**
* Returns the first view that we should snap to.
*
* @param layoutManager the recyclerview's layout manager
* @param helper orientation helper to calculate view sizes
* @return the first view in the LayoutManager to snap to
*/
private View findStartView(RecyclerView.LayoutManager layoutManager,
OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
int firstChild = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
int offset = 1;
if (layoutManager instanceof GridLayoutManager) {
offset += ((GridLayoutManager) layoutManager).getSpanCount() - 1;
}
if (firstChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(firstChild);
float visibleWidth;
// We should return the child if it's visible width
// is greater than 0.5 of it's total width.
// In a RTL configuration, we need to check the start point and in LTR the end point
if (isRtlHorizontal) {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
}
// If we're at the end of the list, we shouldn't snap
// to avoid having the last item not completely visible.
boolean endOfList = ((LinearLayoutManager) layoutManager)
.findLastCompletelyVisibleItemPosition()
== layoutManager.getItemCount() - 1;
if (visibleWidth > 0.5f && !endOfList) {
return child;
} else if (snapLastItem && endOfList) {
return child;
} else if (endOfList) {
return null;
} else {
// If the child wasn't returned, we need to return
// the next view close to the start.
return layoutManager.findViewByPosition(firstChild + offset);
}
}
return null;
}
private View findEndView(RecyclerView.LayoutManager layoutManager,
OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
int lastChild = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
int offset = 1;
if (layoutManager instanceof GridLayoutManager) {
offset += ((GridLayoutManager) layoutManager).getSpanCount() - 1;
}
if (lastChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(lastChild);
float visibleWidth;
if (isRtlHorizontal) {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
}
// If we're at the start of the list, we shouldn't snap
// to avoid having the first item not completely visible.
boolean startOfList = ((LinearLayoutManager) layoutManager)
.findFirstCompletelyVisibleItemPosition() == 0;
if (visibleWidth > 0.5f && !startOfList) {
return child;
} else if (snapLastItem && startOfList) {
return child;
} else if (startOfList) {
return null;
} else {
// If the child wasn't returned, we need to return the previous view
return layoutManager.findViewByPosition(lastChild - offset);
}
}
return null;
}
@Nullable
private View findStartView(RecyclerView.LayoutManager layoutManager,
@NonNull OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
boolean reverseLayout = linearLayoutManager.getReverseLayout();
int firstChild = reverseLayout ? linearLayoutManager.findLastVisibleItemPosition()
: linearLayoutManager.findFirstVisibleItemPosition();
int offset = 1;
if (layoutManager instanceof GridLayoutManager) {
offset += ((GridLayoutManager) layoutManager).getSpanCount() - 1;
}
if (firstChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(firstChild);
float visibleWidth;
if (isRtlHorizontal) {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
}
boolean endOfList;
if (!reverseLayout) {
endOfList = ((LinearLayoutManager) layoutManager)
.findLastCompletelyVisibleItemPosition()
== layoutManager.getItemCount() - 1;
} else {
endOfList = ((LinearLayoutManager) layoutManager)
.findFirstCompletelyVisibleItemPosition()
== 0;
}
if (visibleWidth > 0.5f && !endOfList) {
return child;
} else if (snapLastItem && endOfList) {
return child;
} else if (endOfList) {
return null;
} else {
return reverseLayout ? layoutManager.findViewByPosition(firstChild - offset)
: layoutManager.findViewByPosition(firstChild + offset);
}
}
return null;
}
@Nullable
private View findEndView(RecyclerView.LayoutManager layoutManager,
@NonNull OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
boolean reverseLayout = linearLayoutManager.getReverseLayout();
int lastChild = reverseLayout ? linearLayoutManager.findFirstVisibleItemPosition()
: linearLayoutManager.findLastVisibleItemPosition();
int offset = 1;
if (layoutManager instanceof GridLayoutManager) {
offset += ((GridLayoutManager) layoutManager).getSpanCount() - 1;
}
if (lastChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(lastChild);
float visibleWidth;
if (isRtlHorizontal) {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
}
boolean startOfList;
if (!reverseLayout) {
startOfList = ((LinearLayoutManager) layoutManager)
.findFirstCompletelyVisibleItemPosition() == 0;
} else {
startOfList = ((LinearLayoutManager) layoutManager)
.findLastCompletelyVisibleItemPosition()
== layoutManager.getItemCount() - 1;
}
if (visibleWidth > 0.5f && !startOfList) {
return child;
} else if (snapLastItem && startOfList) {
return child;
} else if (startOfList) {
return null;
} else {
return reverseLayout ? layoutManager.findViewByPosition(lastChild + offset)
: layoutManager.findViewByPosition(lastChild - offset);
}
}
return null;
}
/**
* Returns the first view that we should snap to.
*
* @param layoutManager the recyclerview's layout manager
* @param helper orientation helper to calculate view sizes
* @return the first view in the LayoutManager to snap to
*/
private View findStartView(RecyclerView.LayoutManager layoutManager,
OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
int firstChild = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
if (firstChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(firstChild);
float visibleWidth;
// We should return the child if it's visible width
// is greater than 0.5 of it's total width.
// In a RTL configuration, we need to check the start point and in LTR the end point
if (mIsRtlHorizontal) {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
}
// If we're at the end of the list, we shouldn't snap
// to avoid having the last item not completely visible.
boolean endOfList = ((LinearLayoutManager) layoutManager)
.findLastCompletelyVisibleItemPosition()
== layoutManager.getItemCount() - 1;
if (visibleWidth > 0.5f && !endOfList) {
return child;
} else if (mSnapLastItemEnabled && endOfList) {
return child;
} else if (endOfList) {
return null;
} else {
// If the child wasn't returned, we need to return
// the next view close to the start.
return layoutManager.findViewByPosition(firstChild + 1);
}
}
return null;
}
@Nullable
private View findStartView(RecyclerView.LayoutManager layoutManager,
@NonNull OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
boolean reverseLayout = linearLayoutManager.getReverseLayout();
int firstChild = reverseLayout ? linearLayoutManager.findLastVisibleItemPosition()
: linearLayoutManager.findFirstVisibleItemPosition();
int offset = 1;
if (layoutManager instanceof GridLayoutManager) {
offset += ((GridLayoutManager) layoutManager).getSpanCount() - 1;
}
if (firstChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(firstChild);
float visibleWidth;
if (isRtlHorizontal) {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
}
boolean endOfList;
if (!reverseLayout) {
endOfList = ((LinearLayoutManager) layoutManager)
.findLastCompletelyVisibleItemPosition()
== layoutManager.getItemCount() - 1;
} else {
endOfList = ((LinearLayoutManager) layoutManager)
.findFirstCompletelyVisibleItemPosition()
== 0;
}
if (visibleWidth > 0.5f && !endOfList) {
return child;
} else if (snapLastItem && endOfList) {
return child;
} else if (endOfList) {
return null;
} else {
return reverseLayout ? layoutManager.findViewByPosition(firstChild - offset)
: layoutManager.findViewByPosition(firstChild + offset);
}
}
return null;
}
@Nullable
private View findEndView(RecyclerView.LayoutManager layoutManager,
@NonNull OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
boolean reverseLayout = linearLayoutManager.getReverseLayout();
int lastChild = reverseLayout ? linearLayoutManager.findFirstVisibleItemPosition()
: linearLayoutManager.findLastVisibleItemPosition();
int offset = 1;
if (layoutManager instanceof GridLayoutManager) {
offset += ((GridLayoutManager) layoutManager).getSpanCount() - 1;
}
if (lastChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(lastChild);
float visibleWidth;
if (isRtlHorizontal) {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
}
boolean startOfList;
if (!reverseLayout) {
startOfList = ((LinearLayoutManager) layoutManager)
.findFirstCompletelyVisibleItemPosition() == 0;
} else {
startOfList = ((LinearLayoutManager) layoutManager)
.findLastCompletelyVisibleItemPosition()
== layoutManager.getItemCount() - 1;
}
if (visibleWidth > 0.5f && !startOfList) {
return child;
} else if (snapLastItem && startOfList) {
return child;
} else if (startOfList) {
return null;
} else {
return reverseLayout ? layoutManager.findViewByPosition(lastChild + offset)
: layoutManager.findViewByPosition(lastChild - offset);
}
}
return null;
}
/**
* Returns the first view that we should snap to.
*
* @param layoutManager the recyclerview's layout manager
* @param helper orientation helper to calculate view sizes
* @return the first view in the LayoutManager to snap to
*/
private View findStartView(RecyclerView.LayoutManager layoutManager,
OrientationHelper helper) {
if (layoutManager instanceof LinearLayoutManager) {
int firstChild = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
if (firstChild == RecyclerView.NO_POSITION) {
return null;
}
View child = layoutManager.findViewByPosition(firstChild);
float visibleWidth;
// We should return the child if it's visible width
// is greater than 0.5 of it's total width.
// In a RTL configuration, we need to check the start point and in LTR the end point
if (isRtlHorizontal) {
visibleWidth = (float) (helper.getTotalSpace() - helper.getDecoratedStart(child))
/ helper.getDecoratedMeasurement(child);
} else {
visibleWidth = (float) helper.getDecoratedEnd(child)
/ helper.getDecoratedMeasurement(child);
}
// If we're at the end of the list, we shouldn't snap
// to avoid having the last item not completely visible.
boolean endOfList = ((LinearLayoutManager) layoutManager)
.findLastCompletelyVisibleItemPosition()
== layoutManager.getItemCount() - 1;
if (visibleWidth > 0.5f && !endOfList) {
return child;
} else if (endOfList) {
return null;
} else {
// If the child wasn't returned, we need to return
// the next view close to the start.
return layoutManager.findViewByPosition(firstChild + 1);
}
}
return null;
}
/**
* Returns the first view that we should snap to.
*
* @param layoutManager the RecyclerView's LayoutManager
* @param helper orientation helper to calculate view sizes
* @param gravity gravity to find the closest view
* @return the first view in the LayoutManager to snap to, or null if we shouldn't snap to any
*/
@Nullable
private View findView(@NonNull RecyclerView.LayoutManager layoutManager,
@NonNull OrientationHelper helper,
int gravity,
boolean checkEdgeOfList) {
if (layoutManager.getChildCount() == 0 || !(layoutManager instanceof LinearLayoutManager)) {
return null;
}
final LinearLayoutManager lm = (LinearLayoutManager) layoutManager;
// If we're at an edge of the list, we shouldn't snap
// to avoid having the last item not completely visible.
if (checkEdgeOfList && (isAtEdgeOfList(lm) && !snapLastItem)) {
return null;
}
View edgeView = null;
int distanceToTarget = Integer.MAX_VALUE;
final int center;
if (layoutManager.getClipToPadding()) {
center = helper.getStartAfterPadding() + helper.getTotalSpace() / 2;
} else {
center = helper.getEnd() / 2;
}
final boolean snapToStart = (gravity == Gravity.START && !isRtl)
|| (gravity == Gravity.END && isRtl);
final boolean snapToEnd = (gravity == Gravity.START && isRtl)
|| (gravity == Gravity.END && !isRtl);
for (int i = 0; i < lm.getChildCount(); i++) {
View currentView = lm.getChildAt(i);
int currentViewDistance;
if (snapToStart) {
if (!snapToPadding) {
currentViewDistance = Math.abs(helper.getDecoratedStart(currentView));
} else {
currentViewDistance = Math.abs(helper.getStartAfterPadding()
- helper.getDecoratedStart(currentView));
}
} else if (snapToEnd) {
if (!snapToPadding) {
currentViewDistance = Math.abs(helper.getDecoratedEnd(currentView)
- helper.getEnd());
} else {
currentViewDistance = Math.abs(helper.getEndAfterPadding()
- helper.getDecoratedEnd(currentView));
}
} else {
currentViewDistance = Math.abs(helper.getDecoratedStart(currentView)
+ (helper.getDecoratedMeasurement(currentView) / 2) - center);
}
if (currentViewDistance < distanceToTarget) {
distanceToTarget = currentViewDistance;
edgeView = currentView;
}
}
return edgeView;
}