最近遇到项目整体是Activity搭配DrawerLayout的抽屉样式,在左侧抽屉的顶部,有一个ViewPager无限轮播。
并要求ViewPager左滑下一页,右滑上一页,3秒自动轮播下一页,点击按住停止轮播。
同时DrawerLayout的NavigationMenuView左滑打开,右滑关闭。
滑动事件同时存在,手指滑动头部区域ViewPager响应,滑动其他区域DrawerLayout打开or关闭。
这必然存在滑动冲突。
网上有很多例子,但是都无法完全符合需求设定。
有些是在DrawerLayout打开后,锁定滑动关闭功能,此时DrawerLayout不再接受点击滑动事件,onTouch就必然传递到ViewPager了,等ViewPager滑动到最后一页,在打开滑动关闭功能,此时就滑动关闭了。
这种适用于ViewPager不能无限轮播,和ViewPager占据整个DrawerLayout等抽屉区域。
解决思路:
这是因为点击滑动事件被DrawerLayout消费掉了,如果想让ViewPager接受点击滑动事件,就必须将onTouch传递到ViewPager。
解决方案:
自定义DrawerLayout,重载onInterceptTouchEvent方法。
public class EBDrawerLayout extends DrawerLayout {
public EBDrawerLayout(Context context) {
this(context, null);
}
public EBDrawerLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public EBDrawerLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_MOVE){
if (ev.getY() > 10 && ev.getY() < 300)
return false;
}
return super.onInterceptTouchEvent(ev);
}
}
public class LoopViewPager extends RelativeLayout {
private static final int MESSAGE_LOOP = 5;
@BindView(R.id.vp_loop_pager) ViewPager loopViewPager;
private int loop_ms = 2000;
private Context mContext;
private LoopPagerAdapter loopPagerAdapter;
private List<BannerInfo> bannerInfos;//banner data
private OnBannerItemClickListener onBannerItemClickListener = null;
private Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void dispatchMessage(Message msg) {
super.dispatchMessage(msg);
if (msg.what == MESSAGE_LOOP) {
if (loopViewPager.getCurrentItem() < Short.MAX_VALUE - 1) {
loopViewPager.setCurrentItem(loopViewPager.getCurrentItem() + 1, true);
sendEmptyMessageDelayed(MESSAGE_LOOP, loop_ms);
}
}
}
};
public LoopViewPager(Context context) {
this(context, null);
}
public LoopViewPager(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LoopViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.setClickable(true);
this.mContext = context;
initializeView();
}
private void initializeView() {
View mView = View.inflate(mContext, R.layout.custom_loop_viewpager, this);
ButterKnife.bind(this, mView);
loopViewPager.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
stopLoop();
break;
case MotionEvent.ACTION_UP:
startLoop();
break;
default:
break;
}
return false;
}
});
}
public void updateLoopData(List<BannerInfo> datas) {
if (datas != null && datas.size() > 0) {
this.bannerInfos = datas;
}
loopPagerAdapter = new LoopPagerAdapter(getContext(), bannerInfos, onBannerItemClickListener);
loopViewPager.setAdapter(loopPagerAdapter);
int index = Short.MAX_VALUE / 2 - (Short.MAX_VALUE / 2) % bannerInfos.size();
loopViewPager.setCurrentItem(index);
}
public void setLoop_ms(int loop_ms) {
this.loop_ms = loop_ms;
}
public interface OnBannerItemClickListener {
void onBannerClick(int index, List<BannerInfo> banner);
}
public void setOnBannerItemClickListener(OnBannerItemClickListener onBannerItemClickListener) {
this.onBannerItemClickListener = onBannerItemClickListener;
}
public void startLoop() {
handler.removeCallbacksAndMessages(MESSAGE_LOOP);
handler.sendEmptyMessageDelayed(MESSAGE_LOOP, loop_ms);
}
public void stopLoop() {
handler.removeMessages(MESSAGE_LOOP);
}
}