I was implementing the app tutorial which looks like this.
I made a nice and small ViewPager and placed it on the mock-up ImageView. The problem is that the ViewPager is not scrolled when I try to scroll it from elsewhere, say around the view pager indicators. This is so natural because there's no way that the ViewPager listens to touch event outside of itself.
How can I make ViewPager be scrolled when I try to scroll from elsewhere?
I've tried to detect touch events on the parent of the ViewPager but I couldn't figure out how to relate onFling() or onScroll() to ViewPager's scrolling.
If there's any better suggestion of implementing this kind of UI, what would be it?
Is there any tutorial or custom library similar to this?
set a View.OnTouchListener for your outer ViewPager and check inside if you are on proper page which is displaying inner ViewPager. if inner ViewPager isn't on its first or last you might dispatch MotionEvent to second dispatchTouchEvent(MotionEvent me)
outerViewPager.setOnTouchListener(new OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
if(outerViewPagerAdapter.isCurrentPageHaveInnerViewPager() &&
! innerViewPagerAdapter.isOnFirstOrLastPage()){
innerViewPagerAdapter.dispatchTouchEvent(event);
return true;
}
return super.onTouch(event); //outer will get touch events
}
});
you might also adjust x/y touch cords in event before dispatching if needed
Related
It's my understanding that Android event propagation goes from parent to child, that is to say, it starts with the outermost element and inwards from there. My question is, why is it that when I try to scroll vertically a listview that is inside a viewpager that is wrapped on a scrollview, the listview moves, and not the viewpager.
Okay, let me rephrase that:
I'm trying to create a menu that appears when the user pulls down the view pager, let me make that even clearer:
Scrollview
My custom Menu
ViewPager (with three fragments, all of them have a lisview)
ListView
I understand that what I'm trying to do is a bit odd, but bear with me just for this time. :)
What can I do to "disable" momentarily the list views scrolling.
Thanks
It seems you have to override the scrolling event. A good webpage is Disable scrolling in Android ListView .
Mainly look at dispatchTouchEvent. Snippet of it:
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final int actionMasked = ev.getActionMasked() & MotionEvent.ACTION_MASK;
if (actionMasked == MotionEvent.ACTION_MOVE) {
// Ignore move events
return true;
}
Personally I wish it is simpler than this like disabling scroll method.
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 want to use a ListView (and have done this successfully before) containing custom Views.
Basically these custom views are vertical sliders, obviously conflicting with the natural behaviour of the ListView.
I fill it with my custom Views from an Adapter, and these react to the touches on the Items,
but once I move my finger more than a few pixels, it will scroll, and the custom View will not receive any touch-events anymore.
How can I (nicely) prevent the ListView from scrolling, when I touch my own components?
Can I somehow disable ListView Selection, and just forward the touches to the Items, but still use the scrolling behaviour?
Thank you in advance.
To prevent the scrolling of listview you can inplement on touch listener as follows
listView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_MOVE)
{
return true;
}
return false;
}
});
hope it will work and if it us useful to you give vote
You can intercept all touch events using onInterceptTouchEvent() in your root layout (one that contains the ListView, like a FrameLayout) as found here.
What you do there is capture the motion events (return true when a MotionEvent.ACTION_DOWN comes in), capture the following event in onTouchEvent(), decide whether the motion is meant for the list items or the list itself and accordingly dispatch the events.
Don't expect this to work easily. Understanding the flow of motion events and the interaction between onInterceptTouchEvent() and onTouchEvent() is challenging and making it work even more so. But I'm confident that this is a feasible way to solve your problem.
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.
I have a FiewFlipper that has ListViews as children. I have looked for a way to intercept touch events for a GestureDetector before they reach the children - a method to globally intercept touch events over the ViewFlipper.
Extending FiewFlipper and implementing onInterceptTouchEvent (MotionEvent ev) seemed to be the solution. This works well for most children. However, when the listview begins to scroll, onInterceptTouchEvent stop receiving the events.
I know it's possible to set each listview's OnTouchListener, but this ruins simple hierarchy I'm attempting to create.
Hmm. I once had an activity with a single listview, where I re-populated the adapter as a result of fling gestures. I did it by implementing the dispatchTouchEvent method of the activity:
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
super.dispatchTouchEvent(ev);
return gestureDetector.onTouchEvent(ev);
}
The listview still received the normal events, but my gestureDectector got to taste them too. Perhaps a similar approach will work for you?
As commented by adamp, this behaviour is intentional and does not need to be fought. I applied the gesture listener to the children elements.