我有一个有4个页面的ViewPager,页面将使用runable和handler保持滑动....每个页面都包含一个ImageView,ImageView onClickListener事件在Adapter中设置
ViewPager在初始化时设置了OnTouchListener事件
我正在设置ViewPager OnTouchListener事件,以便在用户触摸viewpager时停止滑动,并在用户松开手指时继续滑动
这是我如何设置ViewPager OnTouchListener事件:
BandsViewPager.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
stopSliding = true;
bandsHandler.removeCallbacks(animateBandsViewPager);
break;
case MotionEvent.ACTION_CANCEL:
break;
case MotionEvent.ACTION_UP:
// calls when touch release on ViewPager
if (bands != null && bands.size() != 0) {
stopSliding = false;
bandsRunnable(bands.size());
bandsHandler.postDelayed(animateBandsViewPager, ANIM_VIEWPAGER_DELAY);
}
break;
case MotionEvent.ACTION_MOVE:
// calls when ViewPager touch
if (bandsHandler != null && stopSliding == false) {
stopSliding = true;
}
break;
}
return false;
}
});
以下是我在ViewPager适配器类中设置ImageView OnClickListener的方法:
mImageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
switch(ClickActionType){
case BAND_CLICK_ACTION_BRAND:
Categories_Fragment categoriesFrag= new Categories_Fragment();
Bundle categoriesArgs = new Bundle();
categoriesArgs.putInt("BrandId", ClickActionTypeId);
categoriesArgs.putInt("TabId", TabId);
if (UI.getAppLanguage() == 0)
categoriesArgs.putString("BrandName", TitleAr);
else
categoriesArgs.putString("BrandName", TitleEn);
categoriesFrag.setArguments(categoriesArgs);
FManager.beginTransaction()
.replace(R.id.main_content, categoriesFrag, Categories_Fragment.ARG_ITEM_ID)
.addToBackStack(Categories_Fragment.ARG_ITEM_ID)
.commit();
break;
case BAND_CLICK_ACTION_ITEM:
Item_Details_Fragment itemDetailsFrag= new Item_Details_Fragment();
Bundle itemDetailsArgs = new Bundle();
itemDetailsArgs.putInt("ItemId", ClickActionTypeId);
itemDetailsFrag.setArguments(itemDetailsArgs);
FManager.beginTransaction()
.replace(R.id.main_content, itemDetailsFrag, Item_Details_Fragment.ARG_ITEM_ID)
.addToBackStack(Item_Details_Fragment.ARG_ITEM_ID)
.commit();
break;
case BAND_CLICK_ACTION_CATEGORY:
Items_Fragment itemsFrag= new Items_Fragment();
Bundle itemsArgs = new Bundle();
itemsArgs.putInt("CategoryId", ClickActionTypeId);
if (UI.getAppLanguage() == 0)
itemsArgs.putString("CategoryName", TitleAr);
else
itemsArgs.putString("CategoryName", TitleEn);
itemsArgs.putInt("BrandId", 0);
itemsArgs.putInt("TabId", TabId);
itemsFrag.setArguments(itemsArgs);
FManager.beginTransaction()
.replace(R.id.main_content, itemsFrag, Items_Fragment.ARG_ITEM_ID)
.addToBackStack(Items_Fragment.ARG_ITEM_ID)
.commit();
break;
default:
}
}
});
如果我删除了ImageView OnClickListener,那么ViewPager将接收触摸事件。
答案 0 :(得分:2)
ImageView
窃取MotionEvent
ViewPager
回调的原因是因为OnTouchListener.onTouch()
的{{1}}方法始终返回ViewPager
。这意味着,在false
方法中,MotionEvent
(您的View
)返回ImageView
之后,它将无法捕获任何新的true
回调。任何可点击的onTouchEvent()
"返回任意View
的{{1}},为true
设置MotionEvent
即可点击。
现在,立即反应可能是使OnClickListener
方法返回View
部分或全部OnTouchListener.onTouch()
语句。但这会使true
拦截所有 case
回调,或者不会为您提供所需的功能。
正确的实现是子类ViewPager
并覆盖MotionEvent
和ViewPager
方法。关键是在onInterceptTouchEvent
中onTouchEvent
的情况下不返回true
,因为这会将每个手势委托给MotionEvent.ACTION_DOWN
。相反,在onTouchEvent
超过"slop"阈值后,{em}拦截<{em} ViewPager
回调。这会将所有后续MotionEvent
次回调发送到MotionEvent.ACTION_MOVE
方法,而不是任何子视图。
Android文档包含managing touch events的最佳做法。如果您想更好地了解Android框架如何处理触摸事件,我还强烈建议您观看Mastering the Android Touch System。