onClick on ViewPager not triggered

后端 未结 8 1137
有刺的猬
有刺的猬 2020-11-28 04:49

I set a click listener on a ViewPager, but the onClick event is never called. I guess the touch event detection of the ViewPager is interfering, bu

相关标签:
8条回答
  • 2020-11-28 05:18

    You can set the focusability of the ViewPager so that it's children can't receive touch events and it takes them instead.

    0 讨论(0)
  • 2020-11-28 05:19

    While this is not an direct answer to how get the onClick triggered, it might very well be an useful answer to the related problem - capturing click events in ViewPager.

    Simply add the onClick attribute in your layout xml file for the pager item and add the method in your activity.

    Sample code:

    PagerAdapter:

    class SamplePagerAdapter extends PagerAdapter {
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            // Inflate a new layout from our resources
            View view = getActivity().getLayoutInflater().inflate(R.layout.pager_item,
                    container, false);
            // Add the newly created View to the ViewPager
            container.addView(view);
            // ... 
    

    layout pager_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        // usual attributes
      >
    
        <ImageButton 
          // usual attributes
          android:onClick="handleAction"
        />
    
     </LinearLayout>
    

    MainActivity:

      public class MainActivity extends Activity {
      /* 
       ...
      */
        public void handleAction(View view) {
          // do your stuff
        }
      }
    
    0 讨论(0)
  • 2020-11-28 05:23

    I solved a similar problem by using a GestureDetector

    Sending the MotionEvent to the GestureDetector

    tapGestureDetector = new GestureDetector(this, new TapGestureListener());
    
    viewPager.setOnTouchListener(new OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                tapGestureDetector.onTouchEvent(event);
                return false;
            }
    });
    

    It you are using the compatibility library, you can change the first line to:

    tapGestureDetector = new GestureDetectorCompat(this, new TapGestureListener());
    

    You can handle your Event in the GestureListener:

            class TapGestureListener extends GestureDetector.SimpleOnGestureListener{
    
             @Override
             public boolean onSingleTapConfirmed(MotionEvent e) {
               // Your Code here
             }
            }
    
    0 讨论(0)
  • 2020-11-28 05:25

    I done like that...

    mViewPager.setOnTouchListener(new View.OnTouchListener() {
        float oldX = 0, newX = 0, sens = 5;
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                oldX = event.getX();
                break;
    
            case MotionEvent.ACTION_UP:
                newX = event.getX();
                if (Math.abs(oldX - newX) < sens) {
                    itemClicked(mViewPager.getCurrentItem());
                    return true;
                }
                oldX = 0;
                newX = 0;
                break;
            }
    
            return false;
        }
    });
    
    0 讨论(0)
  • 2020-11-28 05:27

    The proper way to do this is to implement ViewPager.OnPageChangeListener in your Activity. Here is an example:

    public class MyActivity implements ViewPager.OnPageChangeListener
    {
    
        private ViewPager mViewPager;
        private int mLastPagePosition = -1;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            ...
    
            mViewPager = (ViewPager) findViewById(R.id.viewpager);
            mViewPager.addOnPageChangeListener(this);
    
            ...
        }
    
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            if (mLastPagePosition != position) {
                // the selected page is changed
                mLastPagePosition = position;
            }
        }
    
        @Override
        public void onPageSelected(int position) {
            if (mLastPagePosition != position) {
                // the selected page is changed
                mLastPagePosition = position;
            }
        }
    
        @Override
        public void onPageScrollStateChanged(int state) {
        }
    
    }
    
    0 讨论(0)
  • 2020-11-28 05:42

    Indeed the viewpager is interfering. But you can override the methods of the viewpager to make it do what you want. You'll need to override the ViewGroup.onInterceptTouchEvent(MotionEvent ev) method.

    You could just always return false to allow the touch events to fall through. I would also recommend calling super.onInterceptTouchEvent(ev) to allow swipes to keep working.

    It passes in a MotionEvent, so you could check for clicks with that if you wanted.

    Hope that helps. It should at least get you started. Post back with questions or further problems.

    EDIT:

    Note also that the ViewPager doesn't consume clicks. Therefore you could easily set an onclicklistener on any or all of the children of the viewpager if you wanted to capture clicks and potentially save yourself a lot of work.

    0 讨论(0)
提交回复
热议问题