Is there a way to detect that user is trying to scroll recyclerview and actual scrolling is not happened? For example, the vertical recyclerview is at its top position, and user tries to scroll it up.
Yeah , you can detect the scrolling behaving using onScroll function of recycler view .
recyclerView
.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView,
int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
lastVisibleItem = linearLayoutManager
.findLastVisibleItemPosition();
if (!loading
&& totalItemCount <= (lastVisibleItem + visibleThreshold)) {
// Do something
}
}
});
}
As you can see above , (linearLayoutManager.findLastVisibleItemPosition();) gives you the last visible position , once the user try to scroll the recycler view , it tends to change the last visible position .
Even dx gives you the int: The amount of horizontal scroll and dy (int) gives you the amount of vertical scroll .
This callback will also be called if visible item range changes after a layout calculation. In that case, dx and dy will be 0.
Related
I have recycler view with adapter. Need deny user to scroll to item with 0 index, when it was scrolled. F.e user scrolls to 5 item and when scrolls back first visible will be item with index 1.
Will be glad any ideas how to implement this feature.
Use smoothScrollToIndex(1) inside addOnScrollListener of the recycler view.
Keep a if check with !recyclerView.canScrollVertically(-1) there if it succeeded then use like :
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if(!recyclerView.canScrollVertically(-1))
{
mRecyclerView.smoothScrollToIndex(1);
}
}});
I have a RecyclerView inside a fragment. I need to be notified of scroll changes, so I added a callback to the ScrollChange event (which corresponds to the SetOnScrollChangeListener in classical Android API):
private void RecyclerViewScrollChange(object sender, View.ScrollChangeEventArgs e)
{
int deltaY = e.ScrollY - e.OldScrollY;
}
The problem is that deltaY is always zero, because both ScrollY and OldScrollY are always zero. I am using vertical linear layout in the recycler view's layout manager, so the vertical dimension ought to be updated. What can cause this problem?
View.SetOnScrollChangeListener() was added in API level 23 which you can see here in the docs: View.SetOnScrollChangeListener()
If your app should support versions before API level 23, a workaround is by adding a ScrollChangeListener to the RecyclerView's `ViewTreeObserver' using AddOnScrollChangedListener() as followed:
_recyclerView.ViewTreeObserver.AddOnScrollChangedListener(param);
Or adding a callback to the ViewTreeObserver's ScrollChanged event
scrolling to Y position is getting using
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
Log.v("onScrolled", "dx:" + dx + " dy:" + dy);
}
});
When user scroll the recyclerview, I want a back_to_top button to display when scrolling up, and a load_more button to disappear when scrolling up and display when reaching the end of the list. The OnScrollListener is as below:
mRecyclerViewHome.addOnScrollListener(new OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = layoutManager.getChildCount();
int totalItemCount = layoutManager.getItemCount();
int pastVisibleItems = layoutManager.findFirstVisibleItemPosition();
if (pastVisibleItems + visibleItemCount >= totalItemCount) {
mButtonLoadMore.setVisibility(View.VISIBLE);
Log.i(TAG, "reach bottom detected");
}
// TODO: 7/20/2017 remove shaking
if (dy < 0) { // scrolling up
mButtonLoadMore.setVisibility(GONE);
mButtonToTop.setVisibility(VISIBLE);
}
if (dy > 0) {
mButtonToTop.setVisibility(GONE);
}
}
});
This code works. But the problem is that, if while the recyclerview is scrolling and not stop yet, I interrupt and touch the screen and do another scroll gesture, chance is that the view of the recyclerview is shaking while moving. I guess it's becuase I'm using dy parameter in the code, so that it keeps tracking the value of dy and causes view shaking? Is there anyway to avoid this shaking while detect if the user is scrolling up or down?
can you try disabling item animator
mRecyclerViewHome.setItemAnimator(null);
I have list of images in my Recycler View and on scrolling down the recycler view, onBindViewHolder is called.
I want to call onBindViewHolder again when I scroll up the recycler view so that I can get the position of currently viewed image.
How to call onBindViewHolder again(on scrolling up)?
That might not be the best way to figure out the currently viewed image, however you can add a scroll listener to your recycler view and whenever the dy scroll is negative you can call adapter.notifyDataSetChanged, so onBindViewHolder is called again
mFragmentListBinding.movieGrid.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy < 0) {
mAdapter.notifyDataSetChanged();
}
}
});
I have an activity which contain horizontal RecyclerView which display icons of movies retrieved from server
When the user scroll the recycler view to its end - making the last item of the recycler view visible i want to show "More" button to allow the loading of additional icons
How can i get indication when the user scroll to the end of the recycler view?
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (((LinearLayoutManager) recyclerView.getLayoutManager()).findLastVisibleItemPosition() == LAST_POSITION) {
// code here
}
}
});