onClick没有触发ViewPager

时间:2012-04-20 09:37:08

标签: android android-viewpager

我在ViewPager上设置了一个点击侦听器,但是从不调用onClick事件。我想ViewPager的触摸事件检测是干扰的,但我看不出如何解决它......

有人可以帮忙吗?

由于

mViewPager.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        // never called
    }
}); 

8 个答案:

答案 0 :(得分:104)

我使用GestureDetector解决了类似的问题

将MotionEvent发送到GestureDetector

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

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

您正在使用兼容性库,您可以将第一行更改为:

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

您可以在GestureListener中处理您的活动:

        class TapGestureListener extends GestureDetector.SimpleOnGestureListener{

         @Override
         public boolean onSingleTapConfirmed(MotionEvent e) {
           // Your Code here
         }
        }

答案 1 :(得分:20)

确实,观看者正在干涉。但是你可以覆盖viewpager的方法,使它做你想做的。您需要覆盖ViewGroup.onInterceptTouchEvent(MotionEvent ev)方法。

您可以随时返回false以允许触摸事件通过。我还建议调用super.onInterceptTouchEvent(ev)以允许滑动继续工作。

它会传入MotionEvent,因此您可以根据需要检查点击次数。

希望有所帮助。它应该至少让你开始。回复问题或进一步的问题。

编辑:

另请注意,ViewPager不会消耗点击次数。因此,如果您想捕获点击次数并可能为自己节省大量工作,您可以轻松地在viewpager的任何或所有子项上设置onclicklistener。

答案 2 :(得分:20)

我这样做了......

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;
    }
});

答案 3 :(得分:5)

我知道这是一个很老的话题,但我认为这是更容易解决的问题。

ViewPager viewPager = new ViewPager(this);
viewPager.setAdapter(yourPagerAdapter);

// somewhere where you setup your viewPager add this
viewPager.setOnTouchListener(
    new View.OnTouchListener() {
        private boolean moved;

        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                moved = false;
            }
            if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
                moved = true;
            }
            if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                if (!moved) {
                    view.performClick();
                }
            }

            return false;
        }
    }
);

// then you can simply use the standard onClickListener ...
viewPager.setOnClickListener(
    new View.OnClickListener() {

        @Override
        public void onClick(View view) {
            Log.i(LOG, "Dayum!");
        }
    }
);

答案 4 :(得分:2)

虽然这不是如何触发onClick的直接答案,但它可能是相关问题的有用答案 - 在ViewPager中捕获点击事件。

只需在布局xml文件中为寻呼机项添加onClick属性,并在活动中添加该方法。

示例代码:

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
    }
  }

答案 5 :(得分:0)

您可以设置ViewPager的可聚焦性,以便其子项无法接收触摸事件,而是接受它们。

答案 6 :(得分:0)

确保页面内的其中一个非预期视图不会消耗点击事件。我有一个问题,其中android:clickable在图像视图中为true,我无法从其父级获取click事件。从图像视图中删除该android:clickable后,点击事件现在被发送到其父(BannerView)。请参阅示例代码

public ViewPagerAdapter extends PagerAdapter {
...

public Object instantiateItem (ViewGroup container, int position) {

    MyItem item = this.myItems.get(position);

    BannerView bannerView = new BannerView(container.getContext());
    ImageView imageView = (ImageView) bannerView.findViewById(R.id.header_image);

    this.setupClickListener(bannerView, position);

     container.addView(bannerView);
     return bannerView;
}

private void setupClickListener(final BannerView view, final int position) {

    view.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

               // Page is clicked!
               MyItem item = ViewPagerAdapter.this.myItems.get(position);
               ViewPagerAdapter.this.showNextActivity(view.getContext(), item);               
            }
     });

}

}

答案 7 :(得分:0)

执行此操作的正确方法是在Activity中实现ViewPager.OnPageChangeListener。这是一个例子:

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) {
    }

}