我在ViewPager
上设置了一个点击监听器,但是onClick
事件从未被调用。我猜测ViewPager
的触摸事件检测正在干扰,但我不知道如何解决...
有人能帮忙吗?
谢谢
mViewPager.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// never called
}
});
我在ViewPager
上设置了一个点击监听器,但是onClick
事件从未被调用。我猜测ViewPager
的触摸事件检测正在干扰,但我不知道如何解决...
有人能帮忙吗?
谢谢
mViewPager.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// never called
}
});
我通过使用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
}
}
setOnClickListener
一样,请考虑使用onSingleTapUp
,而不是onSingleTapConfirmed
。否则,事件将在一段时间后触发,以确保它不会被第二次点击跟随。 - minipif我不喜欢那样做...
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;
}
});
确实,ViewPager正在干扰。但你可以覆盖ViewPager的方法使其按照你想要的方式运行。你需要重写ViewGroup.onInterceptTouchEvent(MotionEvent ev)方法。
你只需要始终返回false以允许触摸事件穿过即可。我还建议调用super.onInterceptTouchEvent(ev)以保持滑动的正常工作。
它传递了一个MotionEvent,因此如果你愿意,你可以通过检查它来查找点击。
希望这能帮到你。它至少可以让你开始。如果有问题或进一步的问题,请回复。
编辑:
请注意,ViewPager不会消耗点击事件。因此,如果您想捕获点击并潜在地节省大量工作,您可以轻松地在ViewPager的任何一个或所有子项上设置onclicklistener。
我知道这个话题有些老了,但我认为这是更简单的解决方案。
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!");
}
}
);
虽然这不是如何触发onClick的直接答案,但它很可能是解决相关问题(在ViewPager中捕获点击事件)的有用答案。
只需在您的布局XML文件中为页面项添加onClick属性,并在您的Activity中添加该方法即可。
示例代码:
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);
// ...
布局 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
}
}
您可以设置 ViewPager
的焦点能力,使其子项无法接收触摸事件,而是由它自己处理。
确保页面中的一个意外视图不会消耗点击事件。我曾经遇到过这样的问题,即在图像视图上android:clickable为true,但我无法从其父级获取点击事件。在从图像视图中删除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);
}
});
}
}
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) {
}
}