Custom views preventing swiping in ViewPager - android

I have a ViewPager that is connected to FragmentStatePagerAdapter.
Now each fragment from that FragmentStatePagerAdapter that comes to ViewPager is made up of custom views.
Problem is, if I start swiping on those custom views, ViewPager won't react to swipe, but I have to carefully position my finger between those custom views and then swipe so it catches the swiping motion.
Anyone knows what is the problem? I tried setting those custom views to android:clickable="true" and android:clickable="false" but it didn't work.

in the constructors of your custom views, use requestDisallowInterceptTouchEvent(true);
Also, if your custom view contains a textview, then make sure you replace android:singleLine="true" with android:maxLines="1" otherwise it breaks the viewpager horizontal scrolling ! (Gotta love Google's lovely bugs!)

add this line to your custom view
#Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}

Related

How to make ViewPager scrollable from the parent view?

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

Android touch event propagation

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.

ViewPager in ListView items

I implemented ViewPager in ListView items. In general works perfect, but have some issue.
When I scroll ListView and then touch on screen (during scrolling list) in this case I can't scroll ViewPager in this item, ListView has focus. I should select it again for ability to swipe. ListView has returned SCROLL_STATE_TOUCH_SCROLL state, when I touch it during the scroll. At this moment I should focused on ViewPager for ability to swipe items.
Can I solve this issue without any scroll conflicts in ListView and ViewPager? I guess that it's imposible, but, decided to ask here.
Or, maybe you can advice me to use some other control to implementing swipe in ListView items. But scroll animation should be the same as on ViewPager.
Thanks for any advice.
Depending on your XML, you end up with needing to implement OnTouchListener. If the view you want to handle the event can handle it, then return true, if not false. Then the parent can handle it. You might also want to look at ViewGroups, particularly the onInterceptTouchEvent.

Horizontal and Vertical ViewPager together

I have a list of items (custom objects). This is the main list.
Each of the item in the list has another list of data (URLS). This is the sublist.
I want to show the data from main-list implemented as a vertical viewpager. So, flipping in vertical direction changes the items from the main list. And for the data in each item in the main-list should have the sublist implemented as a horizontal viewpager. So, if the fling is in the horizontal direction it shows me the items in the sublist corresponding to the item in the main list.
Also, vertical fling to any item in the sublist should be able to take to the next item of the mainlist.
Essentially, I am looking at implementing both direction view-pagers. Implementing view-pager in one direction seems to be pretty straight forward. i.e. FragmentActivity hosting a Fragment and a adapter class implementing a FragmentPagerAdapter. But, how should I go about implementing the above functionality?
I tried playing around with some third-party libraries including DirectionalViewPager (it's deprecated though). I am planning to use GestureListeners and animations together to build this effect.
Any pointers on what could be the best way to approach this problem would be very helpful.
Thanks,
I built a solution combining a horizontal viewpager (the parent) with vertical viewpagers (each child) on a single view called DoubleViewPager. I overrode the following methods on vertical viewpager:
public boolean onInterceptTouchEvent(MotionEvent ev)
public boolean onTouchEvent(MotionEvent ev)
When the user triggers those events on each child, they pass it to the parent. Then, if the event is vertical, the child processes it, otherwise, if the event is horizontal, the parent processes it.
Take a look to my DoubleViewPager library, where I implemented this strategy.

TextView inside ViewPager intercepts touch events

I have a ViewPager that contains two fragments. In any of the fragments I can touch a place, swipe to switch to another fragment. One of the fragments contains a list. Items in the list contains one TextView and one ImageView. The issue is, if you dragging has been started from tapping the ImageView, it's OK. But if it's been from the TextView, the drag was never known to the ViewPager, as a result the 'smooth switching' never happens.
Any clue on this?
EDIT
This picture is to show how my GUI is. If the drag has been started from TextViewE, it doesn't begin.
This thing bothered me too, but I've managed to find the answer.
Basically, the case is: if the view can scroll horizontally, it intercepts the horizontal motion event and ViewPager is not able to process it anymore.
Since API Level 14 TextViews have android:scrollHorizontally property (and setHorizontallyScrolling(boolean) method), which, if set to true, causes the TextView to intercept horizontal scroll motion events.
You may set it to false either in XML or right in the code, but watch out: android:singleLine property forces android:scrollHorizontally to be set to true! Very tricky point! But fortunately, you usually able to safely replace single line property with android:maxLines="1" and necessary ellipsize value.
Good luck!
you can override onTouchEvent() of the TextView:
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
return false;
}
return super.onTouchEvent(event);
}

Categories

Resources