Recyclerview measure scroll distance to disable keyboard - android

I want to hide keyboard if user starts scrolling in RecyclerView.
dy is scrolled distance if I understood that correctly, and if it passes certain value, I can hide keyboard.
But I found out if you press and hold the finger on screen and scroll slowly, it will not change dy value (its still 1) that means my method is not working.
Anyone know other alternative how to handle this specific usecase?
Code:
list.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (dy.absoluteValue > KEYBOARD_HIDE_DIST) editText.clearFocus()
}
})

Use this function computeVerticalScrollOffset() on recyclerView it will give the offset of scroll position
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
Log.d("Scrolled","Distance Scrolled : "+ recyclerView.computeVerticalScrollOffset());
}
});
Not started with kotlin yet, Hence I have added java code. Hope you got the thing. Let me know if it works for you

Related

RecyclerView Swipe to delete Prevent delete animation on non-deletable items

I have created a recyclerView with swipe to delete functionality.
I am having an item that I don't want to it to be archived.
I want to implement the swipe on the items that cant be deleted so that the user can scroll a little bit, when he scroll he see's a red background indicating that the item can't be archived and once he stops swiping the swipe will close instead of doing the animation to archive the item.
I have managed to make the item scroll less by doing add this line to my onDrawChild method:
if (hasActiveActions) {
// layout that I don't want to be deleted
super.onChildDraw(c, recyclerView, viewHolder, dX / 5, dY, actionState, isCurrentlyActive)
} else {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
}
The problem is that the animation to delete the item still occurs once the user scrolled enough, I want to get the same behaviour that the item is swipe a little bit but then closes instead of having the animation.
I also tried overriding getMovementFlags:
override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
val adapter = recyclerView.adapter
if (adapter is NotificationsRecyclerViewAdapter) {
if (adapter.itemCount > 0 && adapter.notifications[viewHolder.adapterPosition].hasActiveNotifications())
// disable swipe for item with actions
return 0
}
return super.getMovementFlags(recyclerView, viewHolder)
The problem that it disables the scroll.

How to detect recyclerview’s scrolling outside it bounds?

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.

Deny scroll to first position in recyclerview

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);
}
}});

recyclerview onScrollListener not working correctly

I've got a recyclerView within a pull to refresh layout.
I've added an onScrollListener to keep track of the total vertical movement by adding/subtracting the delta Y (dy) to a variable named totalScrolled.
And if the recyclerview is scrolled fully to the top totalScrolled should be 0 and a view should be visible.
Problem only is that somehow there is a bug and the scroll listener is not accurate in telling me how much the list has scrolled. After scrolling down and back up again through my many items list somehow the totalScrolled doesn't return to 0.
Anyone ran into this issue as well and knows how to solve this?
Instead of using the dy from the scrollListener's onScrolled callback to keep track of the total vertical scroll which is inaccurate I use a function from the recyclerView itself - RecyclerView.computeVerticalScrollOffset() - which accurately keeps track of how many pixels the recyclerView has scrolled.
My code looks something like this:
home_screen_recycler.addOnScrollListener(object: RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val scrollOffset = home_screen_recycler.computeVerticalScrollOffset()
presenter.onListScrolled(scrollOffset)
}
})
In my project I use this logic.
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (arrayList.size() == 0)
return;
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
int itemPosition = mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
if (itemPosition == (arrayList.size() - 1)) {
// here you can fetch new data from server.
}
}
}
});

Swipe Back Activity Android

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 :)

Categories

Resources