I have scrollview. Inside that ScrollView I have some content on top and RecyclerView that starts in the middle of the screen. I want to be able to scroll down until that RecyclerView fill whole ScrollView then i want to be able to scroll in that RecyclerView.
Examples from existing apps: In google plus app on someone's profile, there is some info about user on top but you could scroll down to list of his posts. In Instagram or Facebook is this too.
I tried this:
First i set height of RecyclerView to have the same height as ScrollView.
Then i added OnTouchListener to RecyclerView so it will get scrolls events when ScrollView is scrolled down.
recyclerView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(scrollView.getChildAt(0).getMeasuredHeight() <= scrollView.getScrollY() + scrollView.getHeight()){
v.getParent().requestDisallowInterceptTouchEvent(true);
}
return false;
}
});
It is ok when i want to scroll down but I am unable to scroll back to top to content that isn't inside RecyclerView.
Any ideas how to achieve that? I am also loading more content to RecyclerView as user scrolls down, so i don't know final height of that RecyclerView.
Related
I have a horizontal recyclerView that I populate with imageViews, so that when the user swipes from right to left, the rest of the images appear one by one. Everything is behaving correctly, images are loaded and horizontal scroll works as expected, even the clickListeners for individual items work fine...
BUT... if the touch gesture to scroll to the right is not a pure horizontal swipe (or left if the user reaches the end of the recyclerView and wants to go back), the fragment where the recyclerView is being loaded scrolls down, too. I want to avoid this behavior, so that when the user intends to reach the images swipping from right to left, the recyclerView only moves in the horizontal direction, ignoring any vertical movement that is performed over the recyclerView. If the user taps or swipes outside of the recyclerView screen area, I want usual behavior to occur (scroll down as expected). I have tried with other alternatives seen in this site, like using the setOnTouchListener option to detect a MotionEvent and act accordingly, as you can check below (this is actual code from my fragment):
advertPicturesRecyclerView.setOnTouchListener { recyclerView, motionEvent ->
when(motionEvent.action) {
MotionEvent.ACTION_UP -> {
Snackbar.make(recyclerView, "Touch down!", Snackbar.LENGTH_LONG).show()
recyclerView.parent.requestDisallowInterceptTouchEvent(true)
true
}
else -> {
recyclerView.parent.requestDisallowInterceptTouchEvent(false)
true
}
}
}
In this context, ACTION_UP means in the direction of the recyclerView, so this just detects movement inside the recyclerView and sort of "passes" vertical movement to the parent (fragment), which scrolls down.
How can I "block" the recyclerView to ignore any vertical swipe, and only move horizontally?
val viewManager = LinearLayoutManager(requireContext(),LinearLayoutManager.HORIZONTAL, false)
myRecylcerView?.layoutManager = viewManager
The above snippet will allow only a horizontal scroll based on your question but I guess there is something else that is causing the problem like you might be using a NestedScrollView/ScrollView, so please provide the layout files and a sample video to have a clear perspective of the problem.
Update - 25th September 2020
You can try the below to your NestedScrollView and recylcerview
<androidx.core.widget.NestedScrollView
android:id="#+id/nsvMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never">
// .....
// .....
</androidx.core.widget.NestedScrollView
myRecylcerView?.isNestedScrollingEnabled = false
It would be much better if you attach your layout file.
I have a viewpager, and each page has a scrollview. I want to be able to do scroll vertically and also change page horizontally without raising the finger. The problem is that if I start moving the finger vertically, the scrollview gets the touch events, but if I start moving the finger horizontally, the event is still consumed by scrollview. So I have to raise the finger, and start a new gesture horizontally.
I would like to change this behaviour creating a custom scrollview. If I override onTouchEvent(), I can detect the direction of the event. So I have made something like:
public boolean onTouchEvent(){
if(isVertical()){
return true;
}
return false;
}
My problem is that when I return false, the scrollview stops scrolling, but the touch events are not passed to the viewpager, so I can't swipe to next or previous page.
I have an activity with a ViewPager that covers the whole activity. Inside this ViewPager is a ListView, that only covers the bottom part of the fragment. The ListView recognizes swipe events (you can swipe Items left and right) but when you want to swipe a list item the ViewPager switches the page, so it doesn't work.
Is there an easy way to deal with this problem, so that the ViewPager doesn't receive the touch events that are intended for the list.
Thanks
My first idea is requestDisallowInterceptTouchEvent() may help you.
public boolean onTouch(View v, MotionEvent e) {
if(e.getAction() == MotionEvent.ACTION_DOWN){
listItem.getParent().requestDisallowInterceptTouchEvent(true);
}
}
I have a case which includes 3 ScrollViews stacked following way:
HorizontalScrollView on top and it contains layout, which has ScrollView, which contains layout containing another HorizontalScrollView.
HorizontalScrollView
--------ScrollView
------------HorizontalScrollView
Without the top HorizontalScrollView touch event's work okay, and now I need to disable the top HorizontalScrollView, but allow the child's get events normally, child HorizontalScrollView will eventually scroll the top HorizontalScrollView.
Thanks.
i am not very clear regarding what you want to do but, this should work,
OnTouchListener skipTouchListener = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
//do nothing
return false;
}
};
yourView.setOnTouchListener(skipTouchListener);
This way yourView will not process the touch events.
I have a ViewPager with dynamic number of images in it. This ViewPager is added as a custom row to a table view. As this table view can have multiple dynamic custom rows, I have to add this table view in a scrollview for scrolling.
Now my question is, when I am scrolling horizontally to View Pager, it's not exactly horizontal scrolling, it's mixed with some vertical scrolling as well. So when a vertical scrolling is detected the events are passed to the scroll view; which makes the ViewPager reset to the initial position.
So how can I pass back the events to ViewPager or avoid scrollview catching vertical scroll events?
Note: I tried disabling scrollview to vertical scrolling but that didn't stop it from capturing the vertical scroll events.
I found the solution for my question and this is how I did it.
I over ride the on touch event for my Viewpager in the following way
myViewPager.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_MOVE && myScrollView!=null){
myScrollView.requestDisallowInterceptTouchEvent(true);
}
return false;
}
});
Note: myScrollView is parent of myViewPager, as said in my question.