I have a RecyclerView where I have added different actions that can be performed on the list items. Particularly, DragDrop and SwipeDismiss. DragDrop is initiated by long-press, and SwipeDismiss is initiated by swiping. I have to watch for scroll events to block those actions from happening. It is annoying to be scrolling then it suddenly switched to dragging. Before I would add an OnScrollListener to handle this.
This is what I did before:
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if(newState == RecyclerView.SCROLL_STATE_IDLE){
drag.setCurrentAction(IDLE);
} else {
drag.setCurrentAction(SCROLL);
}
}
No longer will work
I recently added CoordinatorLayout for collapsable toolbars. Now when scrolling up, drag wont get set to SCROLL until the toolbar has been collapsed. I tried to create my own behavior, but that would replace my current behavior I am using; @string/appbar_scrolling_view_behavior. This removed the behaviors I wanted for the toolbar and didn't work to notify my drag state.
What I have tried:
@Override
public boolean onStartNestedScroll(CoordinatorLayout cl, CollapsingToolbarLayout child, View directTargetChild,
View target, int nestedScrollAxes) {
if (nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL) {
if (drag.getCurrentAction().ordinal() < SCROLL.ordinal()) {
/* No actions have started and we are scrolling. set the new action */
drag.setCurrentAction(SCROLL);
}
return true;
}
return super.onStartNestedScroll(cl, child, directTargetChild, target, nestedScrollAxes);
}
@Override
public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, CollapsingToolbarLayout child, View target) {
super.onStopNestedScroll(coordinatorLayout, child, target);
if (drag.getCurrentAction() == SCROLL) {
drag.setCurrentAction(INVALID);
}
}
So my question
How do I listen for those scroll changes on my recycler view that are being intercepted by the CoordinatorLayout? Is a Behavior the correct way?
have you tried to add a touchEvent listener, then deactivate the interceptors events for the parent viewgroup holder? I reckon that returns to the child the control of any touch event you want to handle.
scrollView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Disallow the touch request for parent scroll on touch of child view
v.getParent().requestDisallowInterceptTouchEvent(true);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
v.getParent().requestDisallowInterceptTouchEvent(false);
}
return false;
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With