ViewPager intercepts all x-axis onTouch events. How to disable?
You are right, I believe every scrolling container intercepts touch events, but you can prevent it. You can put a touch listener on your layout:
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
pager.requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
pager.requestDisallowInterceptTouchEvent(false);
break;
}
}
how to disable viewpager adapter on touching specific views?
This first thing that comes to mind for me is to have a custom ViewPager
in which, when your touch listeners get notified of a specific event you could set the swipeable
boolean
in ViewPager
to false and set it back to true whichever way best fits your application.
public class CustomViewPager extends ViewPager {
private boolean swipeable = true;
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
// Call this method in your motion events when you want to disable or enable
// It should work as desired.
public void setSwipeable(boolean swipeable) {
this.swipeable = swipeable;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
return (this.swipeable) ? super.onInterceptTouchEvent(arg0) : false;
}
}
Make sure to change your layout file to show:
<com.your.package.CustomViewPager .. />
Instead of:
<android.support.v4.view.ViewPager .. />
Edit 2
Here is my setup (Working with the above CustomViewPager
):
CustomViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the CustomViewPager with the sections adapter.
mViewPager = (CustomViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
public void swipeOn(View v) {
mViewPager.setSwipeable(true);
}
public void swipeOff(View v) {
mViewPager.setSwipeable(false);
}
The above shown onCreate
is in my MainActivity
class which extends FragmentActivity
and implements ActionBar.TabListener
How to prevent onTouchEvent() method to be called for more than one views at once?
ViewPager
will by default intercept all touch events. In fact, if you put anything inside anything else that scrolls, the container will intercept the touch event. You can override this behavior in certain cases. There is a similar problem with a solution here that might help you:
ViewPager intercepts all x-axis onTouch events. How to disable?
Viewpager intercepts snackbar dismiss
Check out my solution on github.
In case the link is taken down for some reason I'll explain what I did.
- I copied the relevant Snackbar classes into my project.
- Inspired by this answer to a similar question I modified the Behavior subclass of Snackbar to work in a viewpager. Specifically, I find if there is a viewpager as a parent of the snackbar in the view hierarchy. Then when the Snackbar is touched I disable that viewpagers handling of touch events. I reenable it when let go of Snackbar (when the touch event is over).
Here's the important code:
final class Behavior extends SwipeDismissBehavior<SnackbarLayout> {
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, SnackbarLayout child,
MotionEvent event) {
ViewPager vp = getViewPagerParent(child);
if (parent.isPointInChildBounds(child, (int) event.getX(), (int) event.getY())) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
ViewPagerSnackbarManager.getInstance().cancelTimeout(mManagerCallback);
// If touching Snackbar tell the viewpager not to intercept touch events
if (vp != null) {
vp.requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// As soon as this event (touching the Snackbar) is over tell viewpager to resume intercepting touch events
if (vp != null) {
vp.requestDisallowInterceptTouchEvent(false);
}
ViewPagerSnackbarManager.getInstance().restoreTimeout(mManagerCallback);
break;
}
}
return super.onInterceptTouchEvent(parent, child, event);
}
// helper method that move up the view hierarchy searching for a Viewpager and returns it if found. Null if not found.
private ViewPager getViewPagerParent(View child) {
ViewParent parent = child.getParent();
while (parent != null) {
parent = child.getParent();
if (parent instanceof ViewPager) {
return (ViewPager) parent;
} else if (!(parent instanceof View)) {
return null;
} else {
child = (View) parent;
}
}
return null;
}
}
SwipeDismissListViewTouchListener in ListView and ViewPager
I found solution for my error.
In this question I answer how disable onClick method in Fabric library. Can I set custom onClick on my timeline using fabric sdk?
The project is same the project is the same and this related error.
In this method disable views,clickable and long clickable:
//helper method to disable subviews
private void disableViewAndSubViews(ViewGroup layout) {
layout.setEnabled(false);
for (int i = 0; i < layout.getChildCount(); i++) {
View child = layout.getChildAt(i);
if (child instanceof ViewGroup) {
disableViewAndSubViews((ViewGroup) child);
} else {
child.setEnabled(false);
child.setClickable(false);
child.setLongClickable(false);
}
}
}
and disable method to swipe2dismiss /p>
The solution is add on list adapter this lines:
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final View view = super.getView(position, convertView, parent);
//disable subviews to avoid links are clickable
ViewTweetUtils.disableViewAndSubViews((ViewGroup) view);
//enable root view and attach custom listener
view.setEnabled(true);
view.setClickable(false);
return view;
}
view.setEnabled only not works. You must add view.setClickable(false). Why? I don't know but it works.
Thanks for the help
Is it possible to disable scrolling on a ViewPager
A simple solution is to create your own subclass of ViewPager
that has a private boolean
flag, isPagingEnabled
. Then override the onTouchEvent
and onInterceptTouchEvent
methods. If isPagingEnabled
equals true invoke the super
method, otherwise return
.
public class CustomViewPager extends ViewPager {
private boolean isPagingEnabled = true;
public CustomViewPager(Context context) {
super(context);
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return this.isPagingEnabled && super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return this.isPagingEnabled && super.onInterceptTouchEvent(event);
}
public void setPagingEnabled(boolean b) {
this.isPagingEnabled = b;
}
}
Then in your Layout.XML
file replace any <com.android.support.V4.ViewPager>
tags with <com.yourpackage.CustomViewPager>
tags.
This code was adapted from this blog post.
Why are the Fragments in my ViewPager not receiving touch events?
To have the right behavior, I ended up putting the CoordinatorLayout
inside the DrawerLayout
, changing the SlidingTabLayout
to a TabLayout
(and moved it inside the AppBarLayout
of the @layout/top_toolbar
). I also added app:layout_behavior="@string/appbar_scrolling_view_behavior"
to the ViewPager
.
I based my code on the great Cheesesquare demo.
Related Topics
Android - Sharedpreferences with Serializable Object
Play Rtsp Streaming in an Android Application
How to Check How Much Free Space an Sd Card Mounted on an Android Device Has
Sending a File Using Bluetooth Obex Object Push Profile (Opp)
Android Fab Icon Always Black with Materialcomponents Theme
How to Make an Intent with Multiple Actions
How to Get the Size of a Folder on Sd Card in Android
How to Add New Activity to Existing Project in Android Studio
Android: How Does Gridview Auto_Fit Find the Number of Columns
Why Do I Get a Emulator-5554 Disconnected Message
How to Make an Fm Radio Application in Android
Android - Communicating Between Two Devices
How to Be Notified on Wifi Network Status Change
How to Change the Android App Package Name When Assembling with Gradle
Login Error: There Is an Error in Logging You into This Application. Please Try Again Later