Android 未触发 ViewPager 上的 onClick
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10243690/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
onClick on ViewPager not triggered
提问by jul
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, but I can't see how to solve it...
我在 a 上设置了一个点击侦听器ViewPager
,但从未调用过 onClick 事件。我猜触摸事件检测ViewPager
正在干扰,但我看不出如何解决它......
Anybody could help?
有人可以帮忙吗?
Thanks
谢谢
mViewPager.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// never called
}
});
采纳答案by bhekman
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.
事实上,viewpager 正在干扰。但是您可以覆盖 viewpager 的方法以使其执行您想要的操作。您需要覆盖ViewGroup.onInterceptTouchEvent(MotionEvent ev)方法。
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.
您可以始终返回 false 以允许触摸事件失败。我还建议调用 super.onInterceptTouchEvent(ev) 以允许滑动继续工作。
It passes in a MotionEvent, so you could check for clicks with that if you wanted.
它传入MotionEvent,因此您可以根据需要检查点击次数。
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.
另请注意,ViewPager 不消耗点击次数。因此,如果您想捕获点击并可能为自己节省大量工作,则可以轻松地在 viewpager 的任何或所有子项上设置 onclicklistener。
回答by Martin Christmann
I solved a similar problem by using a GestureDetector
我使用 GestureDetector 解决了类似的问题
Sending the MotionEvent to the 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;
}
});
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:
您可以在 GestureListener 中处理您的事件:
class TapGestureListener extends GestureDetector.SimpleOnGestureListener{
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// Your Code here
}
}
回答by Kalpesh
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;
}
});
回答by MarekZeman91
I know it's kinda old topic but I think this is much easier solution.
我知道这是一个古老的话题,但我认为这是更简单的解决方案。
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!");
}
}
);
回答by Tapirboy
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.
虽然这不是如何触发 onClick 的直接答案,但它很可能是对相关问题的有用答案 - 在 ViewPager 中捕获点击事件。
Simply add the onClick attribute in your layout xml file for the pager item and add the method in your activity.
只需在您的布局 xml 文件中为寻呼机项目添加 onClick 属性,并在您的活动中添加该方法。
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
布局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
}
}
回答by tmin
Make sure that one of the unintended views inside the page is not consuming click event. I had an issue where android:clickable was true on the image view and I could not get click event from its parent. After removing that android:clickable from image view, the click events are sent to its parent (BannerView) now. See the example code
确保页面内的非预期视图之一没有消耗点击事件。我有一个问题,其中 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);
}
});
}
}
}
回答by ScouseChris
You can set the focusability of the ViewPager
so that it's children can't receive touch events and it takes them instead.
您可以设置 的可聚焦性,ViewPager
以便它的孩子无法接收触摸事件,而是接受它们。
回答by Lee Hounshell
The proper way to do this is to implement ViewPager.OnPageChangeListener in your Activity. Here is an example:
执行此操作的正确方法是在您的 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) {
}
}