private void initLaunchpad() { mLauncherView.setHasFixedSize(true); StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, OrientationHelper.VERTICAL); mLauncherView.setLayoutManager(layoutManager); mLaunchpadAdapter = new LaunchpadAdapter(this); SmartRecyclerAdapter wrap = new SmartRecyclerAdapter(mLaunchpadAdapter); View footer = new View(this); footer.setLayoutParams(new StaggeredGridLayoutManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, VUiKit.dpToPx(this, 60))); wrap.setFooterView(footer); mLauncherView.setAdapter(wrap); mLauncherView.addItemDecoration(new ItemOffsetDecoration(this, R.dimen.desktop_divider)); ItemTouchHelper touchHelper = new ItemTouchHelper(new LauncherTouchCallback()); touchHelper.attachToRecyclerView(mLauncherView); mLaunchpadAdapter.setAppClickListener((pos, data) -> { if (!data.isLoading()) { mLaunchpadAdapter.notifyItemChanged(pos); mPresenter.launchApp(data); } }); }
@Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { int spanCount = ((GridLayoutManager) parent.getLayoutManager()).getSpanCount(); int orientation = ((GridLayoutManager)parent.getLayoutManager()).getOrientation(); int position = parent.getChildLayoutPosition(view); if(orientation == OrientationHelper.VERTICAL && (position + 1) % spanCount == 0) { outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); return; } if(orientation == OrientationHelper.HORIZONTAL && (position + 1) % spanCount == 0) { outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); return; } outRect.set(0, 0, mDivider.getIntrinsicWidth(), mDivider.getIntrinsicHeight()); }
private void recycleFromStart(RecyclerView.Recycler recycler, int line, LayoutManagerHelper helper) { final OrientationHelper orientationHelper = helper.getMainOrientationHelper(); boolean changed = true; while (helper.getChildCount() > 0 && changed) { View child = helper.getChildAt(0); if (child != null && orientationHelper.getDecoratedEnd(child) < line) { LayoutParams lp = (LayoutParams) child.getLayoutParams(); int position = lp.getViewPosition(); Span span = findSpan(position, child, true); if (span != null) { span.popStart(orientationHelper); helper.removeChildView(child); recycler.recycleView(child); } else { changed = false; } } else { return;// done } } }
private void recycleFromEnd(RecyclerView.Recycler recycler, int line, LayoutManagerHelper helper) { final OrientationHelper orientationHelper = helper.getMainOrientationHelper(); final int childCount = helper.getChildCount(); int i; for (i = childCount - 1; i >= 0; i--) { View child = helper.getChildAt(i); if (child != null && orientationHelper.getDecoratedStart(child) > line) { LayoutParams lp = (LayoutParams) child.getLayoutParams(); int position = lp.getViewPosition(); Span span = findSpan(position, child, false); if (span != null) { span.popEnd(orientationHelper); helper.removeChildView(child); recycler.recycleView(child); } } else { return;// done } } }
@Override int[] calculateDistanceToFinalSnap(@NonNull RecyclerView.LayoutManager layoutManager, @NonNull View targetView) { int[] out = new int[2]; if (layoutManager.canScrollHorizontally()) { out[0] = getDistance(layoutManager, targetView, OrientationHelper.createHorizontalHelper(layoutManager)); } else { out[0] = 0; } if (layoutManager.canScrollVertically()) { out[1] = getDistance(layoutManager, targetView, OrientationHelper.createVerticalHelper(layoutManager)); } else { out[1] = 0; } return out; }
@Override @CallSuper public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view; if (orientation() == OrientationHelper.VERTICAL) { view = inflater.inflate(R.layout.vertical_fragment_brick, container, false); } else { view = inflater.inflate(R.layout.horizontal_fragment_brick, container, false); } RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); recyclerView.setBackgroundColor(recyclerViewBackground); ((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false); dataManager.setRecyclerView(getContext(), recyclerView, orientation(), reverse(), view); return view; }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_show_list); ButterKnife.bind(this); activityComponent().inject(this); mRecyclerView.setAdapter(adapter); int showListCountSpan = getResources().getInteger(R.integer.show_list_count_span); mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(showListCountSpan, OrientationHelper.VERTICAL)); mPresenter.attachView(this); mPresenter.load(savedInstanceState == null); adapter.setItemClickListener((view, item) -> startActivity(ShowDetailsActivity.getOpenIntent(this, item.getId()))); }
private void draw(Canvas c, RecyclerView parent) { RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); if ((layoutManager instanceof LinearLayoutManager)) { LinearLayoutManager manager = (LinearLayoutManager) layoutManager; if (manager.getOrientation() == OrientationHelper.VERTICAL) drawVerticalOrientationDividers(c, parent, manager); else drawHorizontalOrientationDividers(c, parent, manager); } else if (layoutManager instanceof StaggeredGridLayoutManager) { Log.e(getClass().getSimpleName(), "Will soon support this feature !!"); } else { throw new UnsupportedOperationException(getClass().getSimpleName() + " can only be used in the RecyclerView which use GridLayoutManager" + " or LinearLayoutManager or StaggeredGridLayoutManager"); } }
/** * 当item位置变换,滚动recycler到正确的位置 * TODO: 2017/2/21 0021 整理更优雅的写法 还有scrollToPosition(0)是否必要? */ private void scrollToRightPositionWhenItemChanged(RecyclerView recyclerView, View itemView, int itemPos) { final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); if (layoutManager instanceof ItemTouchHelper.ViewDropHandler) { OrientationHelper helper = OrientationHelper.createVerticalHelper(layoutManager); int start = helper.getDecoratedStart(itemView); int end = helper.getDecoratedEnd(itemView); ((LinearLayoutManager) layoutManager).scrollToPositionWithOffset( itemPos, lastItemPos > itemPos ? start : end - itemViewHeight); // System.out.println(lastItemPos + "-" + childPos + "OrientationHelperOrientationHelper:" // + height + "==" + itemViewHeight + "=||=" + start + "===" + end + "||||||" + myStart + "===" + itemTargetView.getHeight() ); } if (lastItemPos == 0 || itemPos == 0) { recyclerView.scrollToPosition(0); } }
@Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { //Fix for bug with bottom selection bar and different month item height in horizontal mode (different count of weeks) View view = rvMonths.getLayoutManager().findViewByPosition(getFirstVisiblePosition(rvMonths.getLayoutManager())); if (view != null) { view.requestLayout(); } if (getCalendarOrientation() == OrientationHelper.HORIZONTAL) { multipleSelectionBarAdapter.notifyDataSetChanged(); //Hide navigation buttons boolean show = newState != RecyclerView.SCROLL_STATE_DRAGGING; ivPrevious.setVisibility(show ? View.VISIBLE : View.GONE); ivNext.setVisibility(show ? View.VISIBLE : View.GONE); } super.onScrollStateChanged(recyclerView, newState); }
@Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); ButterKnife.bind(this, view); int orientation = OrientationHelper.VERTICAL; boolean reverseLayout = false; LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), orientation, reverseLayout); mRecyclerView.setLayoutManager(layoutManager); mRecyclerView.setHasFixedSize(true); mAdapter = new SongsAdapter(); mRecyclerView.setAdapter(mAdapter); // hide whole interface until the fragment is connected with the service hideContent(); }
private int distanceToEnd(View targetView, OrientationHelper helper, boolean fromStart) { if (mIsRtlHorizontal && !fromStart) { return distanceToStart(targetView, helper, true); } return helper.getDecoratedEnd(targetView) - helper.getEndAfterPadding(); }
@Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { int position = parent.getChildAdapterPosition(view); int orientation = 0; int headerCount = 0,footerCount = 0; if (parent.getAdapter() instanceof RecyclerArrayAdapter){ headerCount = ((RecyclerArrayAdapter) parent.getAdapter()).getHeaderCount(); footerCount = ((RecyclerArrayAdapter) parent.getAdapter()).getFooterCount(); } RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); if (layoutManager instanceof StaggeredGridLayoutManager){ orientation = ((StaggeredGridLayoutManager) layoutManager).getOrientation(); }else if (layoutManager instanceof GridLayoutManager){ orientation = ((GridLayoutManager) layoutManager).getOrientation(); }else if (layoutManager instanceof LinearLayoutManager){ orientation = ((LinearLayoutManager) layoutManager).getOrientation(); } if (position>=headerCount&&position<parent.getAdapter().getItemCount()-footerCount||mDrawHeaderFooter){ if (orientation == OrientationHelper.VERTICAL){ outRect.bottom = mHeight; }else { outRect.right = mHeight; } } }
@Override protected void doBusiness() { toolbarTitle.setText("新生攻略"); recyclerView.setLayoutManager(new LinearLayoutManager(context, OrientationHelper.VERTICAL, false)); adapter = new FreshmanGuideAdapter(context, dataList); recyclerView.setAdapter(adapter); recyclerView.addItemDecoration(new DividerItemDecoration(context, OrientationHelper.VERTICAL)); freshmanGuidePresenter = new FreshmanGuidePresenter(this, this); freshmanGuidePresenter.showGuideList(); }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sample); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.main_recyclerview); // Workaround for dash path effect // https://code.google.com/p/android/issues/detail?id=29944 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { recyclerView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } SimpleAdapter adapter = new SimpleAdapter(this); LinearLayoutManager manager = new LinearLayoutManager(this); manager.setOrientation(OrientationHelper.VERTICAL); recyclerView.setLayoutManager(manager); recyclerView.setAdapter(adapter); Paint paint = new Paint(); paint.setStrokeWidth(5); paint.setColor(Color.BLUE); paint.setAntiAlias(true); paint.setPathEffect(new DashPathEffect(new float[]{25.0f, 25.0f}, 0)); recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(this) .paint(paint) .showLastDivider() .build()); }
private int distanceToStart(View targetView, OrientationHelper helper, boolean fromEnd) { if (mIsRtlHorizontal && !fromEnd) { return distanceToEnd(targetView, helper, true); } return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding(); }
/** * Finds the layout orientation of the RecyclerView, no matter which LayoutManager is in use. * * @param layoutManager the LayoutManager instance in use by the RV * @return one of {@link OrientationHelper#HORIZONTAL}, {@link OrientationHelper#VERTICAL} */ public static int getOrientation(RecyclerView.LayoutManager layoutManager) { if (layoutManager instanceof LinearLayoutManager) { return ((LinearLayoutManager) layoutManager).getOrientation(); } else if (layoutManager instanceof StaggeredGridLayoutManager) { return ((StaggeredGridLayoutManager) layoutManager).getOrientation(); } return OrientationHelper.HORIZONTAL; }
private View findOneVisibleChild(int fromIndex, int toIndex, boolean completelyVisible, boolean acceptPartiallyVisible) { OrientationHelper helper; if (layoutManager.canScrollVertically()) { helper = OrientationHelper.createVerticalHelper(layoutManager); } else { helper = OrientationHelper.createHorizontalHelper(layoutManager); } final int start = helper.getStartAfterPadding(); final int end = helper.getEndAfterPadding(); final int next = toIndex > fromIndex ? 1 : -1; View partiallyVisible = null; for (int i = fromIndex; i != toIndex; i += next) { final View child = layoutManager.getChildAt(i); final int childStart = helper.getDecoratedStart(child); final int childEnd = helper.getDecoratedEnd(child); if (childStart < end && childEnd > start) { if (completelyVisible) { if (childStart >= start && childEnd <= end) { return child; } else if (acceptPartiallyVisible && partiallyVisible == null) { partiallyVisible = child; } } else { return child; } } } return partiallyVisible; }
private int distanceToStart(View targetView, OrientationHelper helper, boolean fromEnd) { if (isRtlHorizontal && !fromEnd) { return distanceToEnd(targetView, helper, true); } return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding(); }
@Test public void testTranslateStickyView() { when(adapter.getRecyclerView().getChildCount()).thenReturn(ADAPTER_COUNT); when(adapter.getItemCount()).thenReturn(ADAPTER_COUNT); when(adapter.getRecyclerView().getChildAt(8)).thenReturn(null); footerBehavior.translateStickyView(); verify(recyclerView).getChildAt(8); assertNull(recyclerView.getChildAt(8)); View textView = new TextView(context); when(adapter.getRecyclerView().getChildAt(8)).thenReturn(textView); when(adapter.getRecyclerView().getChildAdapterPosition(textView)).thenReturn(RecyclerView.NO_POSITION); footerBehavior.translateStickyView(); verify(footerBehavior, atLeastOnce()).getStickyViewPosition(RecyclerView.NO_POSITION); when(adapter.getRecyclerView().getChildAdapterPosition(textView)).thenReturn(FOOTER_INDEX); BaseBrick footer = mock(BaseBrick.class); when(adapter.getSectionFooter(FOOTER_INDEX)).thenReturn(footer); when(adapter.indexOf(footer)).thenReturn(FOOTER_INDEX); textView.layout(-BOUNDARY_AXIS, -BOUNDARY_AXIS, -BOUNDARY_AXIS, -BOUNDARY_AXIS); footerBehavior.translateStickyView(); verify(footerBehavior, atLeastOnce()).getStickyViewPosition(FOOTER_INDEX); LinearLayoutManager layoutManager = new LinearLayoutManager(context); layoutManager.setOrientation(OrientationHelper.VERTICAL); when(recyclerView.getLayoutManager()).thenReturn(layoutManager); footerBehavior.translateStickyView(); assertEquals(((LinearLayoutManager)recyclerView.getLayoutManager()).getOrientation(), OrientationHelper.VERTICAL); when(adapter.getRecyclerView()). thenReturn(null); footerBehavior.translateStickyView(); assertNull(adapter.getRecyclerView()); when(dataManager.getBrickRecyclerAdapter()).thenReturn(null); footerBehavior.translateStickyView(); assertNull(dataManager.getBrickRecyclerAdapter()); }
/** * Return the child view that is currently closest to the center of this parent. * * @param layoutManager The {@link RecyclerView.LayoutManager} associated with the attached * {@link RecyclerView}. * @param helper The relevant {@link OrientationHelper} for the attached {@link RecyclerView}. * @return the child view that is currently closest to the center of this parent. */ @Nullable private View findCenterView(RecyclerView.LayoutManager layoutManager, OrientationHelper helper) { int childCount = layoutManager.getChildCount(); if (childCount == 0) { return null; } View closestChild = null; final int center; if (layoutManager.getClipToPadding()) { center = helper.getStartAfterPadding() + helper.getTotalSpace() / 2; } else { center = helper.getEnd() / 2; } int absClosest = Integer.MAX_VALUE; for (int i = 0; i < childCount; i++) { final View child = layoutManager.getChildAt(i); final int childMonthIndex = layoutManager.getPosition(child) % ITEM_PER_MONTH; if (childMonthIndex != ITEM_PER_MONTH / 2) { i += ITEM_PER_MONTH * (childMonthIndex > ITEM_PER_MONTH / 2 ? 1.5f : 0.5f) - childMonthIndex - 1; continue; } int childCenter = helper.getDecoratedStart(child) + (helper.getDecoratedMeasurement(child) / 2); int absDistance = Math.abs(childCenter - center); // if child center is closer than previous closest, set it as closest if (absDistance < absClosest) { absClosest = absDistance; closestChild = child; } } return closestChild; }
private boolean checkSpanForGap(Span span, VirtualLayoutManager layoutManager, int line) { OrientationHelper orientationHelper = layoutManager.getMainOrientationHelper(); if (layoutManager.getReverseLayout()) { if (span.getEndLine(orientationHelper) < line) { return true; } } else if (span.getStartLine(orientationHelper) > line) { return true; } return false; }
private void recycle(RecyclerView.Recycler recycler, LayoutStateWrapper layoutState, Span updatedSpan, int recycleLine, LayoutManagerHelper helper) { OrientationHelper orientation = helper.getMainOrientationHelper(); if (layoutState.getLayoutDirection() == LAYOUT_START) { // calculate recycle line int maxStart = getMaxStart(updatedSpan.getStartLine(orientation), orientation); recycleFromEnd(recycler, Math.max(recycleLine, maxStart) + (orientation.getEnd() - orientation.getStartAfterPadding()), helper); } else { // calculate recycle line int minEnd = getMinEnd(updatedSpan.getEndLine(orientation), orientation); recycleFromStart(recycler, Math.min(recycleLine, minEnd) - (orientation.getEnd() - orientation.getStartAfterPadding()), helper); } }
private int getMaxStart(int def, OrientationHelper helper) { int maxStart = mSpans[0].getStartLine(def, helper); for (int i = 1; i < mNumLanes; i++) { final int spanStart = mSpans[i].getStartLine(def, helper); if (spanStart > maxStart) { maxStart = spanStart; } } return maxStart; }
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { int layout = mScrollOrientation == OrientationHelper.VERTICAL ? R.layout.default_category_start : R.layout.default_category_horizontal; mCategoryView = (CategoryView) inflater.inflate(layout, null); mCategoryView.setLabelRotation(mLabelRotation); mCategoryView.setScrollOrientation(mScrollOrientation); return mCategoryView; }
private int getMaxEnd(int def, OrientationHelper helper) { int maxEnd = mSpans[0].getEndLine(def, helper); Log.d(TAG, "maxEnd " + maxEnd); for (int i = 1; i < mNumLanes; i++) { final int spanEnd = mSpans[i].getEndLine(def, helper); if (spanEnd > maxEnd) { maxEnd = spanEnd; Log.d(TAG, "new maxEnd " + maxEnd + " i " + i); } } return maxEnd; }
void calculateCachedStart(@NonNull OrientationHelper helper) { if (mViews.size() == 0) { mCachedStart = INVALID_LINE; } else { final View startView = mViews.get(0); mCachedStart = helper.getDecoratedStart(startView); } }
int getStartLine(int def, OrientationHelper helper) { if (mCachedStart != INVALID_LINE) { return mCachedStart; } if (def != INVALID_LINE && mViews.size() == 0) { if (mLastEdgeEnd != INVALID_LINE) { return mLastEdgeEnd; } return def; } calculateCachedStart(helper); return mCachedStart; }
void calculateCachedEnd(OrientationHelper helper) { if (mViews.size() == 0) { mCachedEnd = INVALID_LINE; } else { final View endView = mViews.get(mViews.size() - 1); mCachedEnd = helper.getDecoratedEnd(endView); } }
int getEndLine(int def, OrientationHelper helper) { if (mCachedEnd != INVALID_LINE) { return mCachedEnd; } if (def != INVALID_LINE && mViews.size() == 0) { if (mLastEdgeStart != INVALID_LINE) { return mLastEdgeStart; } return def; } calculateCachedEnd(helper); return mCachedEnd; }
void prependToSpan(View view, OrientationHelper helper) { LayoutParams lp = getLayoutParams(view); mViews.add(0, view); mCachedStart = INVALID_LINE; if (mViews.size() == 1) { mCachedEnd = INVALID_LINE; } if (lp.isItemRemoved() || lp.isItemChanged()) { mDeletedSize += helper.getDecoratedMeasurement(view); } }
private int handleOne(LayoutStateWrapper layoutState, LayoutChunkResult result, LayoutManagerHelper helper, boolean layoutInVertical, int parentWidth, int parentHeight, int parentHPadding, int parentVPadding) { int mainConsumed = 0; OrientationHelper orientationHelper = helper.getMainOrientationHelper(); View view = mChildrenViews[0]; final ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( view.getLayoutParams()); if (!Float.isNaN(mAspectRatio)) { if (layoutInVertical) { lp.height = (int) ((parentWidth - parentHPadding) / mAspectRatio); } else { lp.width = (int) ((parentHeight - parentVPadding) * mAspectRatio); } } final float weight = getViewMainWeight(lp, 0); // fill width int widthSpec = helper.getChildMeasureSpec( Float.isNaN(weight) ? (parentWidth - parentHPadding) : (int) ((parentWidth - parentHPadding) * weight), layoutInVertical ? MATCH_PARENT : lp.width, !layoutInVertical); int heightSpec = helper.getChildMeasureSpec(parentHeight - parentVPadding, layoutInVertical ? lp.height : MeasureSpec.EXACTLY, layoutInVertical); helper.measureChildWithMargins(view, widthSpec, heightSpec); mainConsumed = orientationHelper.getDecoratedMeasurement(view) + (layoutInVertical ? getVerticalMargin() + getVerticalPadding() : getHorizontalMargin() + getHorizontalPadding()); calculateRect(mainConsumed, mAreaRect, layoutState, helper); layoutChild(view, mAreaRect.left, mAreaRect.top, mAreaRect.right, mAreaRect.bottom, helper); handleStateOnResult(result, view); return mainConsumed; }
public UIDivider(Context context, int orientation, int dividerColor, Drawable dividerDrawable, int dividerWidth,int marginLeft,int marginRight) { if (orientation != OrientationHelper.HORIZONTAL && orientation !=OrientationHelper.VERTICAL){ throw new IllegalArgumentException("分割线 方向出错"); } if (dividerWidth <0) throw new IllegalArgumentException("分割线 尺寸出错"); mOrientation = orientation; mDividerColor = dividerColor; mDividerDrawable = dividerDrawable; mDividerWidth = dividerWidth; mMarginLeft = marginLeft; mMarginRight = marginRight; initPaint(); }
View findOneVisibleChild(int fromIndex, int toIndex, boolean completelyVisible, boolean acceptPartiallyVisible) { OrientationHelper helper; if (layoutManager.canScrollVertically()) { helper = OrientationHelper.createVerticalHelper(layoutManager); } else { helper = OrientationHelper.createHorizontalHelper(layoutManager); } final int start = helper.getStartAfterPadding(); final int end = helper.getEndAfterPadding(); final int next = toIndex > fromIndex ? 1 : -1; View partiallyVisible = null; for (int i = fromIndex; i != toIndex; i += next) { final View child = layoutManager.getChildAt(i); final int childStart = helper.getDecoratedStart(child); final int childEnd = helper.getDecoratedEnd(child); if (childStart < end && childEnd > start) { if (completelyVisible) { if (childStart >= start && childEnd <= end) { return child; } else if (acceptPartiallyVisible && partiallyVisible == null) { partiallyVisible = child; } } else { return child; } } } return partiallyVisible; }
private int distanceToEnd(View targetView, OrientationHelper helper, boolean fromStart) { if (isRtlHorizontal && !fromStart) { return distanceToStart(targetView, helper, true); } return helper.getDecoratedEnd(targetView) - helper.getEndAfterPadding(); }
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; }