I want to add back to top button in my app. I use recyclerview for displaying items. I added button and when I click on it, view is going to top, but my goal is to show this button only if application is scrolled down or up, and my first item is not visible (I hope thats clear explanation). I tried with
LayoutManager.findFirstCompletelyVisibleItemPosition();
and other methods for LayoutManager but without acceptable effects.
My solution is showed below. I add OnScrollListener on my RecyclerView, and when view is scrolled I check if the first item is visible and I set visibility of my button.
MyRecyclerView.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) {
int visibility = (MyLayoutManager.findFirstCompletelyVisibleItemPosition() != 0) ? View.VISIBLE : View.GONE;
btn.setVisibility(visibility);
}
});
Related
How would you detect when the RecyclerView is near the bottom? Right now it only detects when it's at the absolute bottom and can't scroll anymore:
mGridRecycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(#NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if(!mGridRecycler.canScrollVertically(1) && newState==RecyclerView.SCROLL_STATE_IDLE){
//Make network call here
}
}
});
In your OnScrollListener calculate the difference between the bottom of the last child view in the Recycler view and the bottom of the Recycler view itself, if the last child view is close enough to the bottom of the recycler view you can make your network call.
mGridRecycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(#NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
View view = (View) recyclerView.getChildAt(recyclerView.getChildCount() - 1);
int difference = (view.getBottom() - (recyclerView.getHeight() + recyclerView.getScrollY()));
if (difference == 0) {
//Make network call here
}
}
});
difference == 0 means the absolute bottom when the Recycler view can't scroll anymore, you can change the condition to check when it 5px from the recycler view bottom difference == 5.
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);
}
}});
So if you have a RecyclerView that extends to the end of the screen and use a FloatingActionButton or the third-party FloatingActionMenu, then there is a slight problem with cover-up: If you scroll to the end of the list, the floating button covers up part of the row and there is no way to see or get to what's underneath it.
Is there a way Android allows you to:
Detect if your list has a sufficient number of items in it, i.e. if there is a row at the bottom of the screen visible.
and
Slide the buttons out of the way if you scroll down to the very end, and then slide them back in if you start scrolling back up?
Edit: Or, alternatively, add dynamic padding to the end of the RecyclerView that only shows up if you've scrolled all the way down?
The common pattern to solve the problem of covering up parts of UI is to hide FAB as soon as the user starts scrolling down ... You can achieve this by this code fragment (used with RecyclerView):
fDemandsRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if(dy > 0 ){
if(fFab.isShown()) fFab.hide();
} else {
if(!fFab.isShown()) fFab.show();
}
}
});
If you insist on hiding it on the very end and you are using RecyclerView with LinearLayoutManager, you can check method findLastCompletelyVisibleItemPosition() on the LayoutManager object during the OnScrollListener callback ...
Of course it is possible. The solution was posted here.
The main idea behind it is that FloatingActionButton.Behavior is overriden and changed, so that it reacts to RecyclerView and CoordinatorLayout scrolling.
However, in your case RecyclerViewScrollListener must be different. Here is the implementation:
private class RecyclerViewScrollListener extends RecyclerView.OnScrollListener {
FloatingActionButton mChild;
public RecyclerViewScrollListener(FloatingActionButton child) {
this.mChild = child;
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE && recyclerView.canScrollVertically(Integer.MAX_VALUE)) {
mChild.show();
} else {
mChild.hide();
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (!recyclerView.canScrollVertically(Integer.MAX_VALUE)) {
mChild.hide();
}
}
}
Edit:
When filling RecyclerView with data, invoke such function on it in order to disable or enable scrolling:
private void changeCoordinatorLayoutScrollPossibility(final RecyclerView recyclerView) {
new Handler().post(new Runnable() {
#Override
public void run() {
if (recyclerView.getMeasuredHeight() < alertsRecyclerView.computeVerticalScrollRange()) {
recyclerView.setNestedScrollingEnabled(true);
} else {
recyclerView.setNestedScrollingEnabled(false);
}
}
});
}
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
}
}
});
I have an arraylist of recyclerveiws in another recyclerview and want to know how to scroll all of them when one is scrolled.
This is what I have so far, however it gives me a stack overflow error:
holder.rv.setOnScrollListener(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);
if (dx != -199382734)
for (sched_vh vh : vhs) {
if (vh != holder)
vh.rv.scrollBy(-199382734, dy);
}
}
});
I have worked on this problem with my friend for a few hours..the final answer is really simple.
The main idea is that two recyclerviews should use the same onscrollListener instead of different ones, so that this listener could get which recyclerview is scrolling, and avoid stack over flow. please try following
//rcv and leftrcv are two recyclerviews
RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (recyclerView == leftrcv) {
rcv.removeOnScrollListener(this);
rcv.scrollBy(0, dy);
rcv.addOnScrollListener(this);
} else if (recyclerView == rcv) {
leftrcv.removeOnScrollListener(this);
leftrcv.scrollBy(0, dy);
leftrcv.addOnScrollListener(this);
}
}
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
};
leftrcv.addOnScrollListener(scrollListener);
rcv.addOnScrollListener(scrollListener);
But I don't know whether this will result in performance issue...
Your implementation is probably wrong. You should likely have one RecyclerView that has different view types.
From your comments it seems you want several vertical RecycleViews besides each other and want to horizontally scroll them.
If you want each of the vertical lists fill the screen you'd want to use a ViewPager which allows you to swipe horizontally through a list of views (or fragments).
Otherwise you could have a look at HorzizontalScrollView, though that would only make sense for a small set of vertical lists.