I have a viewpager in the containerActivity hosting two fragments, both having recyclerview, The floating action button is in the container activity, I want to hide fab on recyclerview scrolling.
This StackOverFlow post has the solution
But the problem is how to notify the fab in container activity that the recyclerview in the fragment is scrolled.
I am new to android, So any help would be appreciated.
Thanks!
try this method.
it worked for me
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0 && mFloatingActionButton.getVisibility() == View.VISIBLE) {
mFloatingActionButton.hide();
} else if (dy < 0 && mFloatingActionButton.getVisibility() != View.VISIBLE) {
mFloatingActionButton.show();
}
}});
Related
I have multiple fragment in one activity and want last fragment to infinite scroll, but addOnScrollListener not working when scrolling.
I have success to implement infinite scroll in activity and in a fragment.
In this case I want to implement infinite scroll in activity with multiple child fragment and the only one can infinite scroll is last fragment. When i use addOnScrollListener on last fragment my code not working, I realize the one scrolling is my activity not my fragment that why addOnScrollListener i my fragment not work.
Im using this code for activity and fragment :
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
Toast.makeText(getContext(), "yeah", Toast.LENGTH_SHORT).show();
visibleItemCount = layoutManager.getChildCount();
totalItemCount = layoutManager.getItemCount();
pastVisibleItemCount = layoutManager.findLastVisibleItemPosition();
if (dy > 0) {
if (isLoading) {
if (totalItemCount > previousTotal) {
isLoading = false;
previousTotal = totalItemCount;
}
}
if (!isLoading && (totalItemCount - visibleItemCount) <= (pastVisibleItemCount - itemTreshold)) {
page++;
loadMore();
isLoading = true;
}
}
}
How can I archive only the last fragment can infinite scroll from that case?
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 am using swipe back activity in one of my project activity.
Demo Project Which I have implemented
My activity layout contains recyclerview and other components as well. So the problem is when I scroll up my recyclerview items then activity get finished.
However it is working perfectly in Listview.
So is there any way to prevent activity to finish while recyclerview is scrolling ?
I solved by adding a scroll listener.
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int firstVisibleItem = layoutManager.findFirstCompletelyVisibleItemPosition();
if (firstVisibleItem == 0) {
setEnableSwipe(true);
} else {
setEnableSwipe(false);
}
}
});
I don't know if this is the best solution. But it works :)
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 want to scroll multiple RecyclerView at a time how to achieve that Exp- I have 3 RecyclerView in horizontal and when i scroll 1st RecyclerView then second and third shoul also scroll how to do that ?
The answer is very simple, you have to get scroll feedback from one recycleview and pass it to other recycleviews. But very carefully.
you need to keep referance of which recyclerview starts giving scroll feedback, so that it won't enter into continious loop.
so create a global variable
private int draggingView = -1;
Add scrollListener to all your recyclerviews
mRecyclerView1.addOnScrollListener(scrollListener);
mRecyclerView2.addOnScrollListener(scrollListener);
mRecyclerView3.addOnScrollListener(scrollListener);
your scroll listener should be in this structure. It should decide which recyclerview is giving scroll input and which is receiving.
private RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (mRecyclerView1 == recyclerView && newState == RecyclerView.SCROLL_STATE_DRAGGING) {
draggingView = 1;
} else if (mRecyclerView2 == recyclerView && newState == RecyclerView.SCROLL_STATE_DRAGGING) {
draggingView = 2;
} else if (mRecyclerView3 == recyclerView && newState == RecyclerView.SCROLL_STATE_DRAGGING) {
draggingView = 3;
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (draggingView == 1 && recyclerView == mRecyclerView1) {
mRecyclerView2.scrollBy(dx, dy);
} else if (draggingView == 2 && recyclerView == mRecyclerView2) {
mRecyclerView1.scrollBy(dx, dy);
} else if (draggingView == 3 && recyclerView == mRecyclerView3) {
mRecyclerView1.scrollBy(dx, dy);
}
}
};
Thats all, your recyclerview is ready to scroll. If you scroll one recycleview, it will scroll all other recyclerviews.
Moving is not a problem, stopping is. If user flinged a list, at the same time if he stopped other list, that list will only be stopped, So you need to cover that case too. I hope this explanation and code will solve your problem.