public boolean shouldHandleRecyclerViewLoadingMore(RecyclerView recyclerView) { if (mIsLoadingMore || mCurrentRefreshStatus == RefreshStatus.REFRESHING || mLoadMoreFooterView == null || mDelegate == null || recyclerView.getAdapter() == null || recyclerView.getAdapter().getItemCount() == 0) { return false; } RecyclerView.LayoutManager manager = recyclerView.getLayoutManager(); if (manager == null || manager.getItemCount() == 0) { return false; } if (manager instanceof LinearLayoutManager) { LinearLayoutManager layoutManager = (LinearLayoutManager) manager; if (layoutManager.findLastCompletelyVisibleItemPosition() == recyclerView.getAdapter().getItemCount() - 1) { return true; } } else if (manager instanceof StaggeredGridLayoutManager) { StaggeredGridLayoutManager layoutManager = (StaggeredGridLayoutManager) manager; int[] out = layoutManager.findLastCompletelyVisibleItemPositions(null); int lastPosition = layoutManager.getItemCount() - 1; for (int position : out) { if (position == lastPosition) { return true; } } } return false; }
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; }
public HeaderItemDecoration(RecyclerView.LayoutManager layoutManager, int height) { if (layoutManager.getClass() == LinearLayoutManager.class) { mNumberOfChildren = 1; } else if (layoutManager.getClass() == GridLayoutManager.class) { mNumberOfChildren = ((GridLayoutManager) layoutManager).getSpanCount(); } else if (layoutManager instanceof StaggeredGridLayoutManager) { mNumberOfChildren = ((StaggeredGridLayoutManager) layoutManager).getSpanCount(); } mHeaderHeight = height; }
@Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { currentScrollState = newState; RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); int visibleItemCount = layoutManager.getChildCount(); int totalItemCount = layoutManager.getItemCount(); if ((visibleItemCount > 0 && currentScrollState == RecyclerView.SCROLL_STATE_IDLE && (lastVisibleItemPosition) >= totalItemCount - 1)) { onBottom(); // Scroll to bottom } }
private void handleIntent(Intent intent) { if (intent == null) return; final FollowState followState = intent.getParcelableExtra(WearUIActivity.EXTRA_VEHICLE_FOLLOW_STATE); if (followState != null) { RecyclerView.LayoutManager layoutMgr = followTypesView.getLayoutManager(); if (layoutMgr != null) { layoutMgr.scrollToPosition(adapter.getItemPosition(followState.getMode())); } } }
@Override public void onSaveInstanceState(Bundle outState) { // save list view position mListState = mLayoutManager.onSaveInstanceState(); outState.putParcelable(TransistorKeys.INSTANCE_LIST_STATE, mListState); super.onSaveInstanceState(outState); }
private void initDiscountCardsRecyclerView() { cardsRecyclerView.setHasFixedSize(true); layoutManager = new LinearLayoutManager(getActivity()); cardsRecyclerView.setLayoutManager(layoutManager); Customer customer = new Select().from(Customer.class).executeSingle(); List<DiscountCard> records = customer.discountCards(); adapter = new DiscountCardsListAdapter(records); cardsRecyclerView.setAdapter(adapter); cardsRecyclerView.setItemAnimator(cardsRecyclerView.getItemAnimator()); cardsRecyclerView.addItemDecoration( new HorizontalDividerItemDecoration.Builder(getContext()).build()); cardsRecyclerView.setItemAnimator(new FadeInAnimator()); cardsRecyclerView.getItemAnimator().setRemoveDuration(1000); cardsRecyclerView.setDefaultOnRefreshListener( () -> new Handler() .postDelayed( () -> { // insert things to adapter cardsRecyclerView.setRefreshing(false); layoutManager.scrollToPosition(0); }, 1000)); }
@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); int lastVisibleItem = 0; int firstVisibleItem = 0; RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); int totalItemCount = layoutManager.getItemCount(); if (layoutManager instanceof LinearLayoutManager) { LinearLayoutManager linearLayoutManager = ((LinearLayoutManager) layoutManager); lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition(); firstVisibleItem = linearLayoutManager.findFirstCompletelyVisibleItemPosition(); } else if (layoutManager instanceof GridLayoutManager) { GridLayoutManager gridLayoutManager = ((GridLayoutManager) layoutManager); // 通过LayoutManager找到当前显示的最后的item的position lastVisibleItem = gridLayoutManager.findLastVisibleItemPosition(); firstVisibleItem = gridLayoutManager.findFirstCompletelyVisibleItemPosition(); } else if (layoutManager instanceof StaggeredGridLayoutManager) { StaggeredGridLayoutManager staggeredGridLayoutManager = ((StaggeredGridLayoutManager) layoutManager); // 因为StaggeredGridLayoutManager的特殊性可能导致最后显示的item存在多个,所以这里取到的是一个数组 // 得到这个数组后再取到数组中position值最大的那个就是最后显示的position值了 int[] lastPositions = new int[((StaggeredGridLayoutManager) layoutManager).getSpanCount()]; staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions); lastVisibleItem = findMax(lastPositions); firstVisibleItem = staggeredGridLayoutManager.findFirstVisibleItemPositions(lastPositions)[0]; } if (firstVisibleItem == 0) { if (!mPullLoadMoreRecyclerView.isLoadMore()) { mPullLoadMoreRecyclerView.setPullRefreshEnable(true); } } else { mPullLoadMoreRecyclerView.setPullRefreshEnable(false); } /** 无论水平还是垂直 */ if (!mPullLoadMoreRecyclerView.isRefresh() && mPullLoadMoreRecyclerView.isHasMore() && (lastVisibleItem >= totalItemCount - 1) && !mPullLoadMoreRecyclerView.isLoadMore() && (dx > 0 || dy > 0)) { mPullLoadMoreRecyclerView.setIsLoadMore(true); mPullLoadMoreRecyclerView.loadMore(); } }
@Override public void onViewStateRestored(Bundle savedInstanceState) { super.onViewStateRestored(savedInstanceState); Log.d(TAG, "onViewStateRestored()"); if (savedInstanceState != null) { Parcelable savedRecyclerLayoutState = savedInstanceState.getParcelable(KEY_LAYOUT_MANAGER); mLayoutManager.onRestoreInstanceState(savedRecyclerLayoutState); mAdapter.notifyDataSetChanged(); } }
private void validateRecycler(RecyclerView recycler, boolean headerAlreadyAligned) { RecyclerView.LayoutManager layoutManager = recycler.getLayoutManager(); if (layoutManager == null) { throw new IllegalStateException( "Be sure to call RecyclerViewHeader constructor after setting your RecyclerView's LayoutManager."); } else if (layoutManager.getClass() != LinearLayoutManager.class // not using instanceof on purpose && layoutManager.getClass() != GridLayoutManager.class && !(layoutManager instanceof StaggeredGridLayoutManager)) { throw new IllegalArgumentException( "Currently RecyclerViewHeader supports only LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager."); } if (layoutManager instanceof LinearLayoutManager) { if (((LinearLayoutManager) layoutManager).getOrientation() != LinearLayoutManager.VERTICAL) { throw new IllegalArgumentException( "Currently RecyclerViewHeader supports only VERTICAL orientation LayoutManagers."); } } else if (layoutManager instanceof StaggeredGridLayoutManager) { if (((StaggeredGridLayoutManager) layoutManager).getOrientation() != StaggeredGridLayoutManager.VERTICAL) { throw new IllegalArgumentException( "Currently RecyclerViewHeader supports only VERTICAL orientation StaggeredGridLayoutManagers."); } } if (!headerAlreadyAligned) { ViewParent parent = recycler.getParent(); if (parent != null && !(parent instanceof LinearLayout) && !(parent instanceof FrameLayout) && !(parent instanceof RelativeLayout)) { throw new IllegalStateException( "Currently, NOT already aligned RecyclerViewHeader " + "can only be used for RecyclerView with a parent of one of types: LinearLayout, FrameLayout, RelativeLayout."); } } }
private void maybeFireLoadMore() { if (hasLoadMoreFired) { return; } if (!showShowLoadMore) { return; } final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); int visibleItemCount = layoutManager.getChildCount(); int totalItemCount = layoutManager.getItemCount(); int firstVisibleItemPosition = findFirstVisibleItemPosition(); if (totalItemCount == 0) { return; } if (firstVisibleItemPosition + visibleItemCount + bufferItems > totalItemCount) { if (onLoadMoreListener != null) { hasLoadMoreFired = true; onLoadMoreListener.onLoadMore(adapter.getLastItem()); } } }
private int findPartlyVisiblePosition() { int positionView = 1; RecyclerView.LayoutManager layoutManager = videoList.getLayoutManager(); int start = layoutManager.getPaddingStart(); int end = layoutManager.getHeight() + start; int next = isScrolledUp ? 1 : -1; int fromIndex = isScrolledUp ? 0 : layoutManager.getChildCount() - 1; int toIndex = isScrolledUp ? layoutManager.getChildCount() : -1; for (int i = fromIndex; i != toIndex; i += next) { View child = layoutManager.getChildAt(i); View childTex = child.findViewById(R.id.iv_feed_center_video); int[] texLocation = new int[2]; childTex.getLocationInWindow(texLocation); int childStart = texLocation[VIEW_TOP_LOCATION_INDEX] - actionbarSize; int childEnd = childStart + childTex.getHeight(); if (childStart <= end && childEnd >= start) { positionView = layoutManager.getPosition(child); break; } } return positionView; }
/* Handles adding, deleting and renaming of station */ private void handleCollectionChanges(Intent intent) { // load app state loadAppState(mActivity); int newStationPosition; switch (intent.getIntExtra(TransistorKeys.EXTRA_COLLECTION_CHANGE, 1)) { // CASE: station was added case TransistorKeys.STATION_ADDED: if (intent.hasExtra(TransistorKeys.EXTRA_STATION)) { // get station from intent Station station = intent.getParcelableExtra(TransistorKeys.EXTRA_STATION); // add station to adapter, scroll to new position and update adapter newStationPosition = mCollectionAdapter.add(station); if (mCollectionAdapter.getItemCount() > 0) { toggleActionCall(); } mLayoutManager.scrollToPosition(newStationPosition); mCollectionAdapter.setStationIDSelected(newStationPosition, mPlayback, false); mCollectionAdapter.notifyDataSetChanged(); // TODO Remove? } break; // CASE: station was renamed case TransistorKeys.STATION_RENAMED: if (intent.hasExtra(TransistorKeys.EXTRA_STATION_NEW_NAME) && intent.hasExtra(TransistorKeys.EXTRA_STATION) && intent.hasExtra(TransistorKeys.EXTRA_STATION_ID)) { // get new name, station and station ID from intent String newStationName = intent.getStringExtra(TransistorKeys.EXTRA_STATION_NEW_NAME); Station station = intent.getParcelableExtra(TransistorKeys.EXTRA_STATION); int stationID = intent.getIntExtra(TransistorKeys.EXTRA_STATION_ID, 0); // update notification if (station.getPlaybackState()) { NotificationHelper.update(station, stationID, null, null); } // change station within in adapter, scroll to new position and update adapter newStationPosition = mCollectionAdapter.rename(newStationName, station, stationID); mLayoutManager.scrollToPosition(newStationPosition); mCollectionAdapter.setStationIDSelected(newStationPosition, mPlayback, false); mCollectionAdapter.notifyDataSetChanged(); // TODO Remove? } break; // CASE: station was deleted case TransistorKeys.STATION_DELETED: if (intent.hasExtra(TransistorKeys.EXTRA_STATION) && intent.hasExtra(TransistorKeys.EXTRA_STATION_ID)) { // get station and station ID from intent Station station = intent.getParcelableExtra(TransistorKeys.EXTRA_STATION); int stationID = intent.getIntExtra(TransistorKeys.EXTRA_STATION_ID, 0); // dismiss notification NotificationHelper.stop(); if (station.getPlaybackState()) { // stop player service and notification using intent Intent i = new Intent(mActivity, PlayerService.class); i.setAction(TransistorKeys.ACTION_DISMISS); mActivity.startService(i); LogHelper.v(LOG_TAG, "Stopping player service."); } // remove station from adapter and update newStationPosition = mCollectionAdapter.delete(station, stationID); if (newStationPosition == -1 || mCollectionAdapter.getItemCount() == 0) { // show call to action toggleActionCall(); } else { // scroll to new position mCollectionAdapter.setStationIDSelected(newStationPosition, mPlayback, false); mLayoutManager.scrollToPosition(newStationPosition); } mCollectionAdapter.notifyDataSetChanged(); // TODO Remove? } break; } }
@Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable(KEY_LAYOUT_MANAGER, mLayoutManager.onSaveInstanceState()); super.onSaveInstanceState(outState); }
/** * Returns the adapter item count. * * @return The total number on items in a layout manager */ public int getItemCount() { return layoutManager == null ? 0 : layoutManager.getItemCount(); }
/** * Returns the adapter position of the first visible view. This position does not include adapter * changes that were dispatched after the last layout pass. * * @return The adapter position of the first visible item or {@link RecyclerView#NO_POSITION} if * there aren't any visible items. */ public int findFirstVisibleItemPosition() { final View child = findOneVisibleChild(0, layoutManager.getChildCount(), false, true); return child == null ? RecyclerView.NO_POSITION : recyclerView.getChildAdapterPosition(child); }
/** * Returns the adapter position of the last fully visible view. This position does not include * adapter changes that were dispatched after the last layout pass. * * @return The adapter position of the last fully visible view or {@link RecyclerView#NO_POSITION} * if there aren't any visible items. */ public int findLastCompletelyVisibleItemPosition() { final View child = findOneVisibleChild(layoutManager.getChildCount() - 1, -1, true, false); return child == null ? RecyclerView.NO_POSITION : recyclerView.getChildAdapterPosition(child); }
private float getHeaderY(View item, RecyclerView.LayoutManager lm) { return headerStore.isSticky() && lm.getDecoratedTop(item) < 0 ? 0 : lm.getDecoratedTop(item); }